iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >微信小程序打包插件开发的方法
  • 428
分享到

微信小程序打包插件开发的方法

2023-06-26 08:06:34 428人浏览 独家记忆
摘要

今天小编给大家分享一下微信小程序打包插件开发的方法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。如果你看过文档,相信你一定知

今天小编给大家分享一下微信小程序打包插件开发的方法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

如果你看过文档,相信你一定知道:

  • 每个插件必须要有 apply 方法,用于 webpack 引擎执行你想要执行的代码。

  • 两个重要的对象 Compiler 和 Compilation,你可以在上面绑定事件钩子(WEBpack 执行到该步骤的时候调用),具体有哪些事件钩子可以阅读Compiler hooks。

  • module 和 chunk 的关系,我们可以理解为每个文件都会有一个 module,而一个 chunk 则是由多个 module 来组成。

  • webpack 整个打包流程有那些事件

  • 如何写一个简单的 loader

如果感觉无从着手,可以继续看看我是如何一步步开发并完善 mini-program-webpack-loader 来打包小程序的。

小程序有一个固定的套路,首先需要有一个 app.JSON 文件来定义所有的页面路径,然后每个页面有四个文件组成:.js,.json,.wxml,.wxss。所以我以 app.json 作为 webpack entry,当 webpack 执行插件的 apply 的时候,通过获取 entry 来知道小程序都有哪些页面。

 

这里使用了两个插件 MultiEntryPlugin,SingleEntryPlugin。为什么要这样做呢?因为 webpack 会根据你的 entry 配置(这里的 entry 不只是 webpack 配置里的 entry,import(), require.ensure() 都会生成一个 entry)来决定生成文件的个数,我们不希望把所有页面的 js 打包到一个文件,需要使用 SingleEntryPlugin 来生成一个新的 entry module;而那些静态资源,我们可以使用 MultiEntryPlugin 插件来处理,把这些文件作为一个 entry module 的依赖,在 loader 中配置 file-loader 即可把静态文件输出。伪代码如下:

const MultiEntryPlugin = require('webpack/lib/MultiEntryPlugin'); const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');  class MiniPlugin {    apply (compiler) {        let options = compiler.options        let context = compiler.rootContext        let entry = options.entry        let files = loadFiles(entry)        let scripts = files.filter(file => /\.js$/.test(file))        let assets = files.filter(file => !/\.js$/.test(file))               new  MultiEntryPlugin(context, assets, '__assets__').apply(compiler)                scripts.forEach((file => {            let fileName = relative(context, file).replace(extname(file), '');            new SingleEntryPlugin(context, file, fileName).apply(compiler);        })    } }复制代码

当然,如果像上面那样做,你会发现最后会多出一个 main.js,xxx.js(使用 MultiEntryPlugin 时填的名字),main.js 对应的是配置的 entry 生成的文件,xxx.js 则是 MultiEntryPlugin 生成的。这些文件不是我们需要的,所以需要去掉他。如果熟悉 webpack 文档,我们有很多地方可以修改最终打包出来的文件,如 compiler 的 emit 事件,compilation 的 optimizeChunks 相关的事件都可以实现。其本质上就是去修改 compilation.assets 对象。

在 mini-program-webpack-loader 中就使用了 emit 事件来处理这种不需要输出的内容。 

小程序打包当然没这么简单,还得支持wxml、wxss、wxs和自定义组件的引用,所以这个时候就需要一个 loader 来完成了,loader 需要做的事情也非常简单 —— 解析依赖的文件,如 .wxml 需要解析 import 组件的 src,wxs 的 src,.wxss 需要解析 @import,wxs 的 require,最后在 loader 中使用 loadModule 方法添加即可。自定义组件一开始在 add entry 步骤的时候直接获取了,所以不需要 loader 来完成。

这样做也没什么问题,可是开发体验是比较差的,如再添加一个自定义组件,一个页面,webpack 是无感知的,所以需要在页面中的 .json 发生改变时检查是不是新增了自定义组件或者新增了页面。这个时候遇到一个问题,自定义组件的 js 是不能通过 addModule 的方式来添加的,因为自定义组件的 js 必须作为独立的入口文件。在 loader 中是做不了,所以尝试把文件传到 plugin 中(因为 plugin 先于 loader 执行,所以是可以建立 loader 和 plugin 通信的)。

简单粗暴的方式:

// loader.jsclass MiniLoader {}module.exports = function (content) {    new MiniLoader(this, content)}module.exports.$applyPluginInstance = function (plugin) {  MiniLoader.prototype.$plugin = plugin}// plugin.jsconst loader = require('./loader')class MiniPlugin {    apply (compiler) {        loader.$applyPluginInstance(this);    }}复制代码

但是...。文件是传到 plugin 了,可是再使用 SingleEntryPlugin 时你会发现,没效果。因为在 compiler make 之后 webpack 已经不能感知新的 module 添加了,所以是没有用的,这个时候就需要根据文档猜,怎么样才能让 webpack 感知到新的 module,根据文档中的事件做关键字查询,可以发现在编译完成的时候会调用 compilation needAdditionalPass 事件钩子:

this.emitAssets(compilation, err => {    if (err) return finalCallback(err);        if (compilation.hooks.needAdditionalPass.call()) {    compilation.needAdditionalPass = true;        const stats = new Stats(compilation);    stats.startTime = startTime;    stats.endTime = Date.now();    this.hooks.done.callAsync(stats, err => {    if (err) return finalCallback(err);        this.hooks.additionalPass.callAsync(err => {    if (err) return finalCallback(err);    this.compile(onCompiled);    });    });    return;    }        this.emitRecords(err => {    if (err) return finalCallback(err);        const stats = new Stats(compilation);    stats.startTime = startTime;    stats.endTime = Date.now();    this.hooks.done.callAsync(stats, err => {    if (err) return finalCallback(err);    return finalCallback(null, stats);    });    });    });复制代码

如果在这个事件钩子返回一个 true 值,则可以使 webpack 调用 compiler additionalPass 事件钩子,尝试在这里添加文件,果然是可以的。

 

当然,小程序打包还有些不同的地方,比如分包,如何用好 splitchunk,就不在啰嗦了,当你开始以后你会发现有很多的方法来实现想要的效果。

插件开发到这里差不多了,总的来说,webpack 就是变着花样的回调,当你知道每个回调该做什么的时候,webpack 用起来就轻松了。明显我不知道,因为在开发过程中遇到了一些问题。

遇到的问题

如何在小程序代码中支持 resolve alias,node_modules?

既然是工具,当然需要做更多的事情,有赞的小程序那么复杂,如果支持 resolve alias,node_modules 可以使得项目更方便维护,或许你会说这不是 webpack 最基本的功能吗,不是的,我们当然是希望可以在任何文件中使用 alias,node_modules 支持的不仅仅是 js。当然这样做就意味着事情将变得复杂,首先就是获取文件路径,必须是异步的,因为在 webpack 4 中 resolve 不再支持 sync。其次就是小程序的目录名不能是 node_modules,这时就需要一种计算相对路径的规则,还是相对打包输出的,而不是相对当前项目目录。

多个小程序项目的合并

有赞从小程序来讲,有微商城版,有零售版,以及公共版,其中大多基础功能,业务都是相同的,当然不能再每个小程序在开发一次,所以这个工具具备合并多个小程序当然是必须的。这样的合并稍微又要比从 node_modules 中取文件复杂一些,因为需要保证多个小程序合并后的页面是正确的,而且要保证路径不变。

这两个问题的最终的解决方案既是以 webpack rootContext 的 src 目录为基准目录,以该目录所在路径计算打包文件的绝对路径,然后根据入口文件的 app.json 所在目录的路径计算出最终输出路径。

exports.getDistPath = (compilerContext, entryContexts) => {    return (path) => {    let fullPath = compilerContext    let npmReg = /node_modules/g    let pDirReg = /^[_|\.\.]\//g    if (isAbsolute(path)) {      fullPath = path    } else {      // 相对路径:webpack 最后生成的路径,打包入口外的文件都以 '_' 表示上级目录      while (pDirReg.test(path)) {        path = path.substr(pDirReg.lastIndex)        fullPath = join(fullPath, '../')      }      if (fullPath !== compilerContext) {        fullPath = join(fullPath, path)      }    }    // 根据 entry 中定义的 json 文件目录获取打包后所在目录,如果不能获取就返回原路径    let contextReg = new RegExp(entryContexts.join('|'), 'g')    if (fullPath !== compilerContext && contextReg.exec(fullPath)) {      path = fullPath.substr(contextReg.lastIndex + 1)      console.assert(!npmReg.test(path), `文件${path}路径错误:不应该还包含 node_modules`)    }        if (npmReg.test(path)) {      path = path.substr(npmReg.lastIndex + 1)    }    return path  }}复制代码

如何把子包单独依赖的内容打包到子包内

解决这个问题的方法是通过 optimizeChunks 事件,在每个 chunk 的依赖的 module 中添加这个 chunk 的入口文件,然后在 splitChunk 的 test 配置中检查 module 被依赖的数量。如果只有一个,并且是被子包依赖,则打包到子包内。

webpack 支持单文件失败

这是一个未解决的问题,当尝试使用 webpack 来支持单文件的时候,好像没那么方便:

  • 单文件拆分为四个文件后,可以使用 emitFile 和 aDDDependency 来创建文件,但是创建的文件不会执行 loader

  • 使用 loadModule 会因为文件系统不存在该文件会报错

以上就是“微信小程序打包插件开发的方法”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网精选频道。

--结束END--

本文标题: 微信小程序打包插件开发的方法

本文链接: https://www.lsjlt.com/news/308340.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 微信小程序打包插件开发的方法
    今天小编给大家分享一下微信小程序打包插件开发的方法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。如果你看过文档,相信你一定知...
    99+
    2023-06-26
  • 微信小程序的开发方法
    本篇内容主要讲解“微信小程序的开发方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“微信小程序的开发方法”吧!1、准备工作用没有注册过微信公众平台的邮箱注册一个微信公众号, 申请帐号 , 根据指...
    99+
    2023-06-29
  • 微信小程序 | 小程序组件化开发
    🖥️ 微信小程序 专栏:小程序组件化开发 🧑‍💼 个人简介:一个不甘平庸的平凡人🍬 ✨ 个人主页:CoderHing的个人主页 🍀 格言: ☀️ 路漫漫...
    99+
    2023-09-09
    前端 javascript 开发语言 微信小程序 前端框架
  • 小程序:微信小程序打包成APP
     哈喽大家好 ! 我是小白 本篇将教大家如何一键实现微信小程序打包成APP! 如今的微信小程序发展可谓是如日中天,关于微信小程序和APP谁才是最终的王者的问题一直没有得到一个正式的答案。 2017年1月9日,张小龙在微信公开课上宣布小程序...
    99+
    2023-09-20
    微信小程序 小程序
  • 微信小程序 | 小程序开发
    🖥️ 微信小程序专栏:小程序开发 初级知识 🧑‍💼 个人简介:一个不甘平庸的平凡人🍬 ✨ 个人主页:CoderHing的个人主页 🍀 格言: ☀️ 路漫...
    99+
    2023-09-08
    微信小程序 小程序
  • 提高微信小程序开发效率的方法
    小编给大家分享一下提高微信小程序开发效率的方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!微信小程序小结  在接触的微信小程序开发过程中,不难发现微信小程序为了...
    99+
    2023-06-14
  • 微信小程序 - 云开发
    1、小程序云开发 1.1、云开发简介 小程序·云开发是微信团队联合腾讯云推出的专业的小程序开发服务。开发者可以使用云开发快速开发小程序、小游戏、公众号网页等,并且原生打通微信开放能力。开发者无需搭建服...
    99+
    2023-09-04
    微信小程序 小程序
  • 最新微信小程序抓包方法
    一、安装 fiddler 官网下载:https://www.telerik.com/download/fiddler 二、配置 打开fiddler tools-> options,genneral: 全选 https: connecti...
    99+
    2023-09-01
    微信 小程序
  • 微信小程序开发语言(微信小程序开发教程)详细步骤
    微信小程序开发语言 开发微信小程序用什么语言 1、微信小程序开发所需要的语言比较特别,首先介绍一下需要使用到的文件类型大致分为:WXML(WeiXin Mark Language 微信标记语言)、WX...
    99+
    2023-10-23
    微信小程序 开发语言 小程序
  • 微信小程序中打开内置浏览器的方法
    微信小程序中打开内置浏览器的方法 因为微信小程序本身是不推荐引流到外部的,所以正规的方法其实都是被禁止掉的。 1.wx.openUrl可直接打开内置浏览器页面 (2021年时可以使用,现在已...
    99+
    2023-09-06
    微信小程序 小程序
  • 使用uniapp打包微信小程序时主包和vendor.js过大解决(uniCloud的插件分包)
    1.问题描述 正常的的微信小程序在编译后,主包应保持在2MB左右(限制最大2MB),其余的文件通过分包来进行加载  但是有的情况下,微信小程序的主包能达到3MB,vend...
    99+
    2023-02-21
    uniapp打包体积大 uniapp vendor.js 太大 uniapp打包体积大
  • 微信小程序开发的技巧
    这篇文章主要介绍微信小程序开发的技巧,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!注意:本文默认开发者对微信小程序开发有一定语法基础。小程序开发文档相关免费学习推荐:微信小程序开发微信小程序小结  在接触的微信小程序...
    99+
    2023-06-14
  • 微信小程序组件化如何开发
    本篇内容主要讲解“微信小程序组件化如何开发”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“微信小程序组件化如何开发”吧!组件的定义组件是小程序中的一个重要概念,它能够将页面分解成独立的、可复用的部...
    99+
    2023-07-05
  • uniapp的打包:h5、微信小程序以及APP方式
    uniapp的打包:h5、微信小程序以及APP方式 H5打包微信小程序打包App打包 本人用的是HBuilder编译器,学习uniapp时b站某位大大推荐的,我刚开始接触代码时候也用过,那...
    99+
    2023-09-05
    微信小程序 uni-app 小程序
  • 【微信小程序开发】第 7 课 - 小程序的常用组件
              欢迎来到博主 Apeiron 的博客,祝您旅程愉快 ! 时止则止,时行则行。动静不失其时,其道光明。 目录 1、缘起 2、小程序中组件的分类 3、常用的视图容器类组件  3.1、view 组件 3.2、scroll ...
    99+
    2023-09-23
    微信小程序
  • 怎样开发微信小程序
    小编给大家分享一下怎样开发微信小程序,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!微信小程序 开发经验整理前言:最近小程序出来了...
    99+
    2024-04-02
  • 【微信小程序开发】学习小程序的模块化开发(自定义组件和分包加载)
    前言 模块化开发是一种将复杂的应用程序分解为一系列独立的模块,每个模块负责完成特定的功能的开发方式。模块化开发可以提高代码的可维护性和可复用性,使开发过程更加高效和灵活。 文章目录 前言模块化开发的重要性和优势自定义组件自定...
    99+
    2023-12-22
    小程序 微信小程序 学习 模块开发 前端框架
  • 微信小程序代码包大小的优化方法
    这篇文章主要讲解了“微信小程序代码包大小的优化方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“微信小程序代码包大小的优化方法”吧!setDatasetData是小程序开发中使用最频繁的接口...
    99+
    2023-06-26
  • 微信小程序第三方开发平台接入的方法
    本文小编为大家详细介绍“微信小程序第三方开发平台接入的方法”,内容详细,步骤清晰,细节处理妥当,希望这篇“微信小程序第三方开发平台接入的方法”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。微信第三方平台开发接入授权...
    99+
    2023-06-26
  • java微信小程序开发教程
    这篇文章将为大家详细讲解有关java微信小程序开发教程,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Java 微信小程序开发教程 简介 Java 微信小程序是一种基于 Java 语言开发的微信小程序框架,...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作