VPS参考测评推荐
专注分享VPS主机优惠信息
衡天云优惠活动
华纳云优惠活动
荫云优惠活动

美杜莎微信小程序工程实践方案详解

主机参考:VPS测评参考推荐/专注分享VPS服务器优惠信息!若您是商家可以在本站进行投稿,查看详情!此外我们还提供软文收录、PayPal代付、广告赞助等服务,查看详情!
我们发布的部分优惠活动文章可能存在时效性,购买时建议在本站搜索商家名称可查看相关文章充分了解该商家!若非中文页面可使用Edge浏览器同步翻译!PayPal代付/收录合作

美杜莎微信小程序工程实践方案详解

前言我曾经发表过《实战web pack --微信小程序工程化探索》一文,这是我探索微信小程序工程化的第一阶段。起初,我只是想验证微信小程序和webpack是否可以结合(很大程度上是出于对技术的好奇心),并没有过多考虑工程的持续交付。但在内部需求的不断冲击下,我开始有了用工程手段不断简化微信小程序开发难度的想法,最终衍生出的产品是以美杜莎命名的微信小程序快速开发方案。接下来,我将更详细地分享实现此方案的实际过程,下面提到的工具也已发布在npm上供大家下载和使用。本文将涵盖之前发表文章的所有内容,内容更丰富,因此篇幅较长。请耐心看完。

web pack -Build -迷你程序web pack -Build -迷你程序是Medusa的基础和核心。该工具包提供了使用webpack构建微信小程序的能力,我们可以利用Web Pack的生态系统不断丰富Medusa的功能。在讲基础建设配置之前,我们先来看看美杜莎的目录结构基础。只有有了相应的目录约束,项目才能更加规范。

|-- dist编译结果目录|-- src源代码目录| |-- app.js项目入口文件|| -- app.json小程序配置文件||| --sitemap。JSON sitemap配置文件||| --资产静态资源存储目录|||||| --。gitkeep || --组件公共组件存储目录|||| --。gitkeep ||| --Dicts公共字典存储目录||||| --。gitskeep | | | --libs第三方工具库存目录(从外部导入)|第三方工具库存目录git keep | | | --服务API服务存储目录||||| -。git keep ||| --样式|||| --index.less项目常规样式||| -- theme.less项目主题样式| | | --模板公共模板存储目录|||| --。gitkeep |||| --utils公共封装函数存储目录(自封装)| |--。gitkeep|--。env环境变量配置文件|-- config.yaml编译配置文件| -- webpack.config.js webpack配置扩展文件|-- project.config.json开发者工具配置文件└ └──包。json复制代码基础篇webpack现在已经成为前端工程师的必备技能,其复杂的工作原理总是让我们对它心生敬畏,因此在制作微信小程序构建策略的过程中,我们首先将它简单理解为“搬运”。经过一些处理后,它将源目录中的文件输出到目标目录。现在让我们弄清楚我们要移动哪些文件。微信小程序涉及的主要有:

逻辑文件。json配置文件。JSON模板文件。wxml样式文件。wxss。更少。scss脚本文件。wxs静态资源文件资产/基本处理功能接下来,我们将编写webpack公共部分的配置,并使用插件copy-webpack-plugin来完成大多数文件的处理。

/* * config/web pack . common . js */const copy plugin = require(“copy -web pack -plugin“);const config = { context: SOURCE,dev tool:& # 39;无& # 39;,条目:{ app:& # 39;。/app . js & # 39;},输出:{文件名:& # 39;【姓名】。js & # 39,path: DESTINATION },plugins:【new copy plugin(【{ from:& # 39;资产/& # 39;,收件人:& # 39;资产/& # 39;,输入:& # 39;dir & # 39},{ from:& # 39;**/*.wxml & # 39,输入:& # 39;dir & # 39},{ from:& # 39;**/*.wxss & # 39,输入:& # 39;dir & # 39},{ from:& # 39;**/*.json & # 39,输入:& # 39;dir & # 39},{ from:& # 39;**/*.wxs & # 39,输入:& # 39;dir & # 39} ]) ]};通过复制上面的代码,我们实现了除逻辑文件和预编译语言文件之外的处理工作。在配置中,有两个常量SOURCE和DESTINATION,它们分别代表源代码目录和目标代码目录的绝对路径,我们从单独的字典文件中提取它们:

/* * libs/dicts . js */const path = require(“path“);出口。ROOT = process . CWD();出口。SOURCE = path . resolve(this。根,& # 39;src & # 39);出口。DESTINATION = path . resolve(this。根,& # 39;dist & # 39);出口。NODE _ ENV = process . argv . splice(2,1)【0】;复制代码上携带的文件不需要特殊的内容处理,因此完全由插件实现。对于剩下的两类文件,我们需要使用webpack的入口、插件和加载器来配合完成处理工作。

核心门户功能首先我们要解决如何生成门户的问题,而只有解决了门户生成的问题,才能在loader的帮助下完成文件内容的转换。对于门户生成的问题,我开发了另一个插件entry -extract -web pack -plugin来解决。我不打算详细解释这个插件的实现过程,我只解释它的核心实现思想(如果您有兴趣进一步了解,可以下载并直接查看源代码)。事实上,微信小程序建立入口网络是有规律可循的。主包和子包将在app.json文件中配置,页面所需的组件也将在【page】中配置。json文件。抓住这个特点,我们可以列出实现插件功能的核心如下:

通过node.js提供的path和fs模块的功能,基于app.json文件中配置的路径,递归查找每个页面所依赖的组件路径,最后整合到同一个数组中。使用webpack提供的SingleentryPlugin和MultiEntryPlugin,在entryOption的生命周期挂钩中将第一步中收集的路径数组注入到构造中以形成一个条目。如果在监控过程中添加了新页面,则在watchRun生命周期中,新条目会添加到之前的条目中。以上三点是实现生成门户功能的核心思想。除了核心思想之外,我还想简要说明如何编写webpack插件:

class EntryExtractPlugin {构造函数(选项){} apply(编译器){ compiler . hooks . entry option . tap(& # 39;EntryExtractPlugin & # 39, () => { ...});compiler . hooks . watch run . tap(& # 39;EntryExtractPlugin & # 39, () => { ...});}}用于复制代码webpack的插件以类的形式存在。当您使用该插件时,它将自动执行apply方法,然后使用compiler.hooks对象上的各种生命周期属性将我们需要的处理逻辑植入webpack的构造过程中。

逻辑和风格解决了生成词条的问题,然后我们在原有的基础上改进策略。因为预编译语言有很多种类型,为了策略的扩展性,我将样式部分中的策略分成单独的部分,然后通过webpack-merge的工具进行合并。完整的实现如下:

/* * config/web pack . parts . js */exports . load CSS =({ reg =/\。css$/,include,exclude,use =【】})=》({ module:{ rules:【{ include,exclude,test: reg,use:【{ loader:require(& # 39;mini-css-extract -plugin & # 39;).loader },{ loader:& # 39;css-加载程序& # 39;} ].concat(use)}】} });copy code/* * config/web pack . com mon . js */const { merge } = require(& # 39;web pack -合并& # 39;);const minicsextractplugin = require(& # 39;mini-css-extract -plugin & # 39;);const parts = require(& # 39;。/web pack . parts . js & # 39;);常量配置= {...模块:{规则:【{ test: /\。js$/,loader:& # 39;babel -加载程序& # 39;,exclude:/node _ modules/}】},插件:【...新的minicsextractplugin({ filename:& # 39;【姓名】。wxss & # 39}) ]};module . export = merge(【config,parts . load CSS({ reg:/\。减去$/,使用:【& # 39;第三课+装载机& # 39;] })]);复制上面的代码是基本的webpack策略,然后我们可以编写一个工具包的可执行文件,以通过medusa-server {mode}在项目中使用webpack提供的功能。我们需要在工具包的package.json文件中配置bin字段,该字段指示我们将通过命令自动执行哪个文件。

{...main:“index . js“,bin:{“medusa -server“:“index . js“} } Copy code/* * index . js */const webpack = require(& # 39;网络包& # 39;);const { merge } = require(& # 39;web pack -合并& # 39;);const chalk = require(& # 39;粉笔& # 39;);const common config = require(& # 39;。/config/web pack . common & # 39;);const { NODE _ ENV } = require(& # 39;。/libs/dicts & # 39;);const config =(function(mode){ if(mode = = = & # 39;生产& # 39;){ return merge(【common config,{ mode }】);} return merge(【common config,{ mode:& # 39;发展& # 39;,watch: true,watch options:{ ignored:/NODE _ modules/}】)})(NODE _ ENV);webpack(config,(err,stats)=》{ if(err){ console . log(chalk . red(err . stack | | err));if(err . details){ console . log(chalk . red(err . details));}返回未定义的;} const info = stats . toj son();if(stats . haserrors()){ console . log(chalk . red(info . errors));} if(stats . has warnings()){ console . log(chalk . yellow(info . warnings));}});在复制代码的基本章节中完成的webpack配置可以满足两个功能,一个是输出常规文件,另一个是具有两种不同的开发和生产模式。关于基本文章我还有两点需要说明:为什么没有将ES6(变更版本)的相关插件应用到ES5?在实践中发现,async/await语法在10.x版本的IOS中无法正常使用,因此我们简单地使构造更纯粹,然后启用ES6到ES5的功能以及微信开发者工具的增强编译,官方工具将处理新功能。为什么devtool设置为none?不需要sourceMap吗?微信官方已经原生提供了SourceMap功能,当你上传版本时,这个功能已经体现在开发者工具中了。接下来,我们将进入高级章节。在满足正常输出后,它似乎与原始开发没有太大区别,这完全没有体现出webpack的作用,因此我们应该利用webpack及其相关工具生态的能力来扩展Medusa的功能。接下来,我们将为美杜莎提供以下函数:

Path Alias @根据环境自动注入对应的环境域名ESLint和StyleLint代码规范。检查路由功能。Common code extract环境变量webpack可扩展路径别名@原生微信小程序仅支持引入相对路径,但不可避免的是,我们将不得不移动一些文件。假设这个文件在很多地方被引用,这将是一个令人头疼的问题。所以我们可以通过webpack的能力和配置文件jsconfig.json有更好的开发体验。

/* * config/web pack . common . js */const config = {...解析:{别名:{ & # 39;@':SOURCE } } }复制代码{“编译器选项“:{“base URL“:“。“,“路径“:{“@/*“:【“。/src/*“】、}、“target“:“es6“、“module“:“commonjs“、“AllowSyntheticDefaultImports“:true、}、“include“:【“src/* */*“】、“exclude“:【“node _ modules“】、}复制的代码由别名配置,@符号可以引用src源代码目录。然后在实际业务项目的根目录下创建一个jsconfig.json文件。通过上述配置,您可以在使用vscode编辑器时获得良好的智能路径提示功能。

自动注入相应的环境域名。在介绍这个功能之前,我需要解释一下配置文件config.yaml的功能。这是我最初构思的扩展各种功能的配置文件,它应用在实际业务项目的根目录中。目前它的功能还比较少,但未来应该会逐步迭代增加。

#当前项目应用平台platform:wx # Style unit px to rpx scale设置css_unit_ratio: 1#域名配置development _ host:API:https://www . miniprogram . dev . comproduction _ host:API:https://www.miniprogram.pro.com复制代码域名配置可以自由增减,书写形式如示例所示。当我们配置与其中的环境相对应的域名时,我们可以轻松地使用mc访问域名。业务代码中的$hosts.api变量。在构建过程中,该工具会自动帮助您将与环境对应的域名注入代码中,您不再需要关心如何在不同的环境中管理和切换域名。我是这样实现这个功能的:

/**库/字典*/导出。CONFIG = path . resolve(this。根,& # 39;config.yaml & # 39);出口。DEFAULT _ CONFIG = { platform:& # 39;wx & # 39,css_unit_ratio: 1,};copy code/* * libs/index . js */const fs = require(& # 39;fs & # 39);const YAML = require(& # 39;js-YAML & # 39;);const { CONFIG,DEFAULT _ CONFIG } = require(& # 39;。/dicts & # 39;);出口。yaml config =(function(){ try {/* *将YAML格式的内容解析为object */const config = YAML . load(fs . read file sync(config,{ encoding:& # 39;ut F-8 & # 39;}));返回配置;} catch(e){ return DEFAULT _ CONFIG;}})();copy code/* * webpack.com mon . js */const web pack = require(& # 39;网络包& # 39;);const { YAML config } = require(& # 39;../libs & # 39;);const { NODE _ ENV } = require(& # 39;../libs/dicts & # 39;);常量配置= {...插件:【...新网络包。define plugin({ MC:JSON . stringify({ $ hosts:YAML config【` $ { NODE _ ENV } _ host `】| | { } })】};复制代码webpack。DefinePlugin插件识别代码中的标识符mc然后执行相应的替换功能,从而保证代码的正常运行。

ESLint和StyleLint编码标准已经成为一个老生常谈的话题。今年,我的前端团队已经扩充到20多人。在多人协作和不同成员的维护下,我们迫切需要一个统一的编码标准来降低维护成本。(关于规范落地我还有两个题外话要说。当我们需要一个规范时,不要停留在讨论规则上,也不要考虑利用人们的自律来约束编码。如果你的团队也需要实现这些东西,我希望你能做一个先行者,先制定第一个版本的规则,然后找到一个合适的工具,通过工具来约束人们的行为。)接下来,让我们看看我们需要的检查工具是如何配置的:

/* * web pack . common . js */const StylelintPlugin = require(& # 39;stylelint-web pack -插件& # 39;);const config = { module:{ rules:【{ enforce:& # 39;pre & # 39,测试:/\。js$/,exclude: /node_modules/,loader:& # 39;es lint -加载程序& # 39;,选项:{ fix: true,cache: false,formatter:require(& # 39;eslint -friendly -格式化程序& # 39;)} }】},插件:【new StylelintPlugin({ fix:true,files:& # 39;**/*.(sa | sc | le | wx | c)ss & # 39;}) ]};上面配置的两个工具可以按照一定的规则检查js和style文件,一些不符合规范的代码可以自行修复,无法自动修复的部分会给出相应的提示。您可以通过。eslintrc和。业务项目根目录中的stylelintrc文件(我将在下一章扩展规范)。

常用代码提取在应用webpack之后,我们已经为npm提供了为微信小程序的开发加载依赖项的能力。在模块化打包机制下,工具包会被加载到引用它的门户中,这将导致微信小程序包的大小很容易超过限制,因此我们的解决方案是将多次出现的代码提取到单个公共部分中。具体实现代码如下:

/* * config/web pack . common . js */const config = {...输出:{...,全局对象:& # 39;全球& # 39;},插件:【...新网络包。banner plugin({ raw:true,include:& # 39;app.js & # 39,横幅:& # 39;const vendors = require(。/vendors);\nconst commons = require(。/commons));\nconst manifest = require(。/manifest“);'})】,优化:{缓存组:{供应商:{区块:& # 39;初始& # 39;,名称:& # 39;供应商& # 39;,test:/【\ \/】node _ modules【\ \/】/,minChunks: 3,优先级:20 },commons:{ chunks:& # 39;初始& # 39;,名称:& # 39;commons & # 39,test:/【\ \/】(实用程序|库|服务| apis |模型|操作|布局)【\ \/】/,minChunks: 3,优先级:10 } },runtime chunk:{ name:& # 39;清单& # 39;} }};复制代码微信小程序的全局变量可以通过global访问,因此我们需要将output.globalObject属性设置为global。webpack中内置的BannerPlugin插件可以在指定文件的开头插入我们需要的语句,通过它,我们可以将提取的公共文件重新引入依赖关系网格。

我们将看到文件的环境变量。env当我们使用Vue和React的脚手架创建项目时。它的主要功能是扩展开发人员所需的环境变量。在微信小程序中扩展环境变量的需求可能很少,但我们可以改变思路,我们可以用它来扩展开发人员需要的全局变量。接下来,我们将使用工具dotenv-webpack来实现该功能,它可以读取。env文件放在业务项目的根目录下,这样我们也可以在编码中使用变量值。

/* * config/web pack . common . js */const Dotenv = require(& # 39;doten v-网络包& # 39;);const { ENV _ CONFIG } = require(& # 39;../libs/dicts & # 39;);常量配置= {...插件:【...new Dotenv({ path:ENV _ CONFIG })】};复制代码webpack扩展我已经通过webpack实现了许多常用功能,但我的公司开发的微信小程序有很多,因此难免有些项目需要个性化定制策略。既然有这样的需求,我们就应该将这种能力提供给业务开发人员,一来可以从多个项目中吸收更多需要集成的功能点,二来可以暂时减轻我们的负担。事实上,webpack-merge工具是在前面的样式部分中合并的。我已经用过了。我们只需要提供业务项目webpack配置的路径,然后修改前面的执行文件。

/* * index . js */const { web pack _ CONFIG } = require(& # 39;。/libs/dicts & # 39;);const config =(function(mode){ if(mode = = = & # 39;生产& # 39;){ return merge(【common CONFIG,{ mode },web pack _ CONFIG】);} return merge(【common config,{ mode:& # 39;发展& # 39;,watch: true,watch options:{ ignored:/NODE _ modules/} },web pack _ CONFIG】)})(NODE _ ENV);...复制代码路由功能微信官方提供了一个关于路由跳转的API,但我认为官方API在日常开发中有几个不便之处:

您需要输入完整的路径字符串。这条路太长了,记不住。如果修改页面路径,则需要投入很高的维护成本。跳转的方式有很多种,其中navigateTo是常用的方式。因为有许多API和参数,所以在使用它们时不可避免地不需要再次查阅文档。任何官方API的最终目标页面中收到的查询都是字符串类型,这在一定程度上限制了我们的编码设计。为了解决上述三个问题,我对API进行了第二次打包,并消除了四种跳转类型的差异。四种跳转方法的效果可以通过统一的界面实现。并且通过webpack的全局变量注入功能,优化了路径字符串的获取,使用方便,易于维护。Mc。$routes我将页面的文件夹名称与路径相关联,如果它们形成映射关系,我们只需写入文件夹名称。原来我们需要使用pages/home/index来访问主页。经过我的改造,我们可以通过mc访问主页。$ routes . home medusa -WX-路由器medusa -WX-路由器是我对路由功能进行二次打包的工具包。具体实现过程这里就不细说了。您可以自行下载使用或根据需要进行新的改造。下面我将只展示如何在mc的业务代码中使用它。$路线:

MC . router to({ URL:MC。$routes.home,类型:& # 39;推& # 39;,查询:{ id: 0,bool: true },success:()=》console . log(& # 39;成功地& # 39;)});/**推送快捷方式*/MC . router to(MC . routes . home,{ID: 0,bool:true });复制代码为了节省导入路由工具包的步骤,我使用了插件webpack。提供插件以自动补充使用它的导入功能。

/* * config/web pack . common . js */const config = {...插件:【...新网络包。provide plugin({ & # 39;mc.routerTo & # 39: ['medusa -wx-路由器& # 39;, 'routerTo & # 39], '解码& # 39;: ['medusa -wx-路由器& # 39;, '解码& # 39;], 'mc.back & # 39: ['medusa -wx-路由器& # 39;, 'back & # 39], 'mc.goHome & # 39: ['medusa -wx-路由器& # 39;, 'goHome & # 39], }) ]};复制代码规范是项目的重要部分。团队必须根据同一套规则进行编码。规范的存在可以提高代码的质量,对规范的统一理解使成员之间更容易、更高效地相互移交项目。在之前的实践中,我已经将标准化检查工具集成到了构建过程中。在本节中,我将补充应用于微信小程序的规则集配置和相关编辑器插件。当然,我也希望您能阅读我对命名规范的一些总结,希望对您有所启发。规则集实际上是一个包含规则的配置文件,然后我会给出具体的配置内容。当然,考虑到规则集的团队定制和升级,我将ESLint和StyleLint的规则制作成了npm包,解决了所有业务项目统一规则的问题。对应的npm包是eslint-config-medusa和stylelint-config-medusa,这是我的团队需要的,所以你可以结合你的团队的现有情况在实践中进行更改。

# EditorConfig太牛了:https://editor config . org # top-most editor config file root = true【*】charset = ut F-8 indent _ style = space indent _ size = 2 end _ of _ line = lfin sert _ final _ newline = true【*。MD】Trim _ trailing _ white space = false复制代码会创建一个。业务项目根目录中的editorconfig文件,它可以与VS代码插件的EditorConfig结合使用,对常规文件执行基本的编码约束。

module . exports = { parserOptions:{ ECMA version:“2018“,source type:“module“},parser:“babel -eslint“,env: { node: true,commonjs: true,es6: true },globals: { mc: false,wx: true,swan: true,App: true,Page: true,Component: true,Behavior: true,getApp: true,getCurrentPages: true },extends:【“Airbnb -base“】,rules: { //不允许使用控制台“NO-underscore -dangle & # 39;: '关& # 39;,//指定程序中一行的最大长度“max -len“:【“error“,120】,//要求返回语句总是或从不指定值“consistent -return“:【“error“,{“treatundefinedas unspecified“:true }】,//不允许在语句位置使用表达式“NO-unused -expressions“:“off“},设置:{“import/resolver“:{ alias:{ map:【“@“,“。/src“】,【“utils“,“。/src/utils“】,【“服务“,“。/src/services“】】,扩展名:【“。js“,“。json“,“。less“】} } };复制代码模块。exports = { rules:{//disallow未知类型选择器& # 39;选择器-类型-NO-未知& # 39;:null,//不允许未知单元& # 39;unit -NO-未知& # 39;:null },扩展:【& # 39;style Lin T-config -standard & # 39;, '样式-配置-接收-订单& # 39;】,插件:【& # 39;style lint -订单& # 39;]};上面的复制代码显示了我已经完成的两个规则集依赖包的条目文件。安装完依赖包后,我们可以将它们引入。eslintrc和。通过扩展字段对业务项目的文件进行样式化。借助vscode editor的ESLint和stylelint-plus插件,它们可以在编码过程中提醒您相应的错误规则。

上面提到的脚手架的建造和规范都是为特定的商业项目服务的。在具备基本能力后,我们应该思考如何让业务开发人员快速开发出符合要求的业务系统。这样他们就不再需要考虑如何对目录达成一致、如何集成工具以及如何应用编码规范。为了满足快速开发的要求,我着手制作具有初始化项目的简单功能的脚手架。最后,我将这个工具分为两个项目,一个是具有初始化项目结构和下载相关依赖包功能的@chirono/medusa-cli,另一个是具有约定项目结构和必要配置文件的miniprogram-base。业务开发人员只需通过npm在全球范围内安装@chirono/medusa-cli工具,他们可以通过medusa create命令初始化工程项目。该工具还将提示开发人员输入必要的项目信息,这些信息将用于改进业务项目的package.json文件。

结语以上是我对美杜莎项目的总结。现在这个项目已经进入了一个相对稳定的阶段,并成功地投入到许多实际项目中。上述总结的某些部分可能相对简短。如果你感兴趣,我建议你直接下载源代码来学习,因为编码的实际操作不是三言两语就能解释清楚的。我写这篇文章主要是想表达工程链接的完整性可以为实际的项目开发带来可观的收益,而实际的工程不仅仅是单个工具的开发,还包括工具的串接。接下来,我可能还会总结UI打包、TS编译和测试工具方面的知识。最后,感谢您的阅读。如果您有任何问题或建议,可以留言与我讨论。

以上是美杜莎微信小程序工程实践方案的详细内容。更多资讯请关注主机参考其他相关文章!

这几篇文章你可能也喜欢:

本文由主机参考刊发,转载请注明:美杜莎微信小程序工程实践方案详解 https://zhujicankao.com/99270.html

【腾讯云】领8888元采购礼包,抢爆款云服务器 每月 9元起,个人开发者加享折上折!
打赏
转载请注明原文链接:主机参考 » 美杜莎微信小程序工程实践方案详解
主机参考仅做资料收集,不对商家任何信息及交易做信用担保,购买前请注意风险,有交易纠纷请自行解决!请查阅:特别声明

评论 抢沙发

评论前必须登录!