构建配置

mpx深度定制开发了一个webpack插件@mpxjs/webpack-plugin,基于该插件使用webpack进行小程序的编译构建工作。

自动配置

如果你不熟悉webpack,可以通过脚手架进行快速配置


手动配置

webpack.config.js

  1. var MpxWebpackPlugin = require('@mpxjs/webpack-plugin')
  2. var webpackConfig = {
  3. module: {
  4. rules: [
  5. // mpx文件必须设置正确的loader,参考下文详细的loader设置options
  6. {
  7. test: /\.mpx$/,
  8. use: MpxWebpackPlugin.loader({
  9. // `only`模式下,样式前加上注释/* use rpx */可将该段样式中所有的px转换为rpx
  10. transRpx: 'only',
  11. comment: 'use rpx'
  12. })
  13. },
  14. // 对本地图片资源提供增强,编译成小程序支持的格式
  15. // <style>中的图片会被强制转为base64,
  16. // 其他地方引用的资源小于limit的会被转base64,否则会被打包到dist/img目录下通过小程序路径引用
  17. // 由于微信小程序中<cover-image>不支持传base64,可以在图像资源链接后加上`?fallback`查询字符串强制跳过转base64步骤
  18. // 参考下文详细的设置@mpxjs/url-loader的方法
  19. {
  20. test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  21. loader: '@mpxjs/url-loader',
  22. options: {
  23. limit: 10000,
  24. name: 'img/[name].[ext]'
  25. }
  26. }
  27. ]
  28. },
  29. // mpx主插件,必须设置,参考下文详细的插件设置options
  30. plugins: [
  31. new MpxWebpackPlugin({
  32. // 微信模式下设置为`wx`,支付宝模式下设置为`ali`
  33. mode: 'wx'
  34. })
  35. ],
  36. // sourceMap: 小程序不支持eval,因此不要设置为eval相关的sourceMap类型。
  37. // 注意:webpack4新增的mode属性设置为development的时候,会将devtool默认设置为eval,
  38. // 必须手动设置devtool为非eval相关类型来覆盖默认配置
  39. devtool: false,
  40. output: {
  41. // filename设置不能更改
  42. filename: '[name].js'
  43. },
  44. // 通过webpack分包能力减少小程序体积,参考下文的详细介绍
  45. optimization: {
  46. runtimeChunk: {
  47. name: 'bundle'
  48. },
  49. splitChunks: {
  50. chunks: 'all',
  51. name: 'bundle',
  52. minChunks: 2
  53. }
  54. }
  55. }

@mpxjs/webpack-plugin

webpack.config.js

  1. var MpxWebpackPlugin = require('@mpxjs/webpack-plugin')
  2. webpackconfig = {
  3. plugins: [
  4. new MpxWebpackPlugin(options)
  5. ],
  6. }

options

  • mode

    String

    • wx代表编译微信小程序

    • ali代表编译支付宝程序


MpxWebpackPlugin.loader

@mpxjs/webpack-plugin暴露了一个静态方法MpxWebpackPlugin.loader作为.mpx文件的loader

webpack.config.js

  1. var MpxWebpackPlugin = require('@mpxjs/webpack-plugin')
  2. webpackconfig = {
  3. module: {
  4. rules: [
  5. {
  6. test: /\.mpx$/,
  7. use: MpxWebpackPlugin.loader(options)
  8. }
  9. ]
  10. }
  11. }

options

  • transRpx

    Object | boolean | string

    • false关闭转换rpx

    • 'all'普通样式中的px全部转换为rpx,rpx注释样式不转换

    • 'only'普通样式中的px全部不转换为rpx,rpx注释样式转换

    • Object包含属性:mode/comment/designWidth/include/exclude

      include/exclude属性的用法和webpack对module.rules里的规则是一样的,参考webpack文档-exclude

  • comment (即将废弃外层写法,迁移至transRpx内层)

    String

    <style>中的注释内容与options.comment一致时,会被识别为一个rpx注释

  • designWidth (即将废弃外层写法,迁移至transRpx内层)

    Number

    设计稿宽度,单位为px。默认值为750px

    mpx会基于小程序标准的屏幕宽度baseWidth 750rpx,与option.designWidth计算出一个转换比例transRatio

    转换比例的计算方式为transRatio = (baseWidth / designWidth)。精度为小数点后2位四舍五入

    所有生效的rpx注释样式中的px会乘上transRatio得出最终的rpx值

    例如:

    1. /* 转换前:designWidth = 1280 */
    2. .btn {
    3. width: 200px;
    4. height: 100px;
    5. }
    6. /* 转换后: transRatio = 0.59 */
    7. .btn {
    8. width: 118rpx;
    9. height: 59rpx;
    10. }

rpx注释样式

根据rpx注释的位置,mpx会将一段css规则或者一条css声明视为rpx注释样式

开发者可以声明一段rpx注释样式,提示编译器是否转换这段css中的px

例子

  • 全局转换px至rpx,除了某些rpx注释样式之外

webpack.config.js

  1. webpackconfig = {
  2. module: {
  3. rules: [
  4. {
  5. test: /\.mpx$/,
  6. use: MpxWebpackPlugin.loader({
  7. transRpx: {
  8. mode: 'all',
  9. comment: 'use px',
  10. designWidth: 750,
  11. include: resolve('src')
  12. },
  13. })
  14. }
  15. ]
  16. }
  17. }

index.mpx

  1. <style lang="css">
  2. /* use px */
  3. .not-translate-a {
  4. font-size: 100px;
  5. padding: 10px;
  6. }
  7. .not-translate-b {
  8. /* use px */
  9. font-size: 100px;
  10. padding: 10px;
  11. }
  12. .translate-a {
  13. font-size: 100px;
  14. padding: 10px;
  15. }
  16. .translate-b {
  17. font-size: 100px;
  18. padding: 10px;
  19. }
  20. </style>

第一个注释位于一个选择器前,是一个css规则注释,整个规则都会被视为rpx注释样式

第二个注释位于一个css声明前,是一个css声明注释,只有font-size: 100px会被视为rpx注释样式

transRpx = all模式下,除了这两条rpx注释样式之外,其他都会转rpx

  • 只对某些rpx注释样式进行转rpx,全局其他px不转

webpack.config.js

  1. webpackconfig = {
  2. module: {
  3. rules: [
  4. {
  5. test: /\.mpx$/,
  6. use: MpxWebpackPlugin.loader({
  7. transRpx: 'only',
  8. comment: 'use rpx',
  9. designWidth: 750
  10. })
  11. }
  12. ]
  13. }
  14. }

index.mpx

  1. <style lang="css">
  2. .not-translate-a {
  3. font-size: 100px;
  4. padding: 10px;
  5. }
  6. .not-translate-b {
  7. font-size: 100px;
  8. padding: 10px;
  9. }
  10. /* use rpx */
  11. .translate-a {
  12. font-size: 100px;
  13. padding: 10px;
  14. }
  15. .translate-b {
  16. /* use rpx */
  17. font-size: 100px;
  18. padding: 10px;
  19. }
  20. </style>

第一个注释位于一个选择器前,是一个css规则注释,整个规则都会被视为rpx注释样式

第二个注释位于一个css声明前,是一个css声明注释,只有font-size: 100px会被视为rpx注释样式

transRpx = only模式下,只有这两条rpx注释样式会转rpx,其他都不转


@mpxjs/url-loader

受限于小程序既有的能力,目前在小程序中加载本地图片资源会有诸多限制:

  • <style>中的css属性值只能使用base64引用图片,无法用本地路径
  • <template>中的<cover-image>组件的src属性只能通过本地路径,不能使用base64
  • <template>中的其他组件,例如<image>的src属性既可以用本地路径,又可以用base64

@mpxjs/url-loader对这些限制提供了增强。开发者在源码中无需书写base64,通过统一的路径方式引入图片资源,最终编译成小程序支持的代码。

想深入的了解@mpxjs/url-loader对小程序对图片资源的支持,查看mpx图像资源处理了解更多细节

安装

  1. npm install @mpxjs/url-loader

webpack.config.js

  1. webpackconfig = {
  2. module: {
  3. rules: [
  4. {
  5. test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  6. loader: '@mpxjs/url-loader',
  7. options: /* options */
  8. }
  9. ]
  10. }
  11. }

options

仅对<template>和<script>中的资源生效,因为<style>里的资源会强制做base64

  • limit

    Number

    单位为byte,小于limit的资源会被base64,反之会被打包成资源

  • name

    String

    设置图片被打包后的路径: 'img/[name].[ext]'

内联资源query options

  • fallback

    Any

    通过内联query options,可以对指定的资源强制使用资源打包。

    这对于<cover-image>组件引用图片资源非常有效,因为<cover-image>组件不能用base64

例子

文件目录

  1. component
  2. │-- index.mpx
  3. │-- bg-img1.png
  4. │-- bg-img2.png
  5. │-- bg-img3.png

webpack.config.js

  1. webpackconfig = {
  2. module: {
  3. rules: [
  4. {
  5. test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  6. loader: '@mpxjs/url-loader',
  7. otions: {
  8. limit: 10000,
  9. name: 'img/[name].[ext]'
  10. }
  11. }
  12. ]
  13. }
  14. }

index.mpx

  1. <template>
  2. <image src="./bg-img1.png"></image>
  3. <image src="./bg-img2.png"></image>
  4. <cover-image src="./bg-img3.png?fallback">
  5. </template>

bg-img1.png大于10KB,会被打包成资源

bg-img2.png小于10KB,会被做base64

bg-img3.png需要在路径后添加fallback强制打包资源


output.filename

小程序限定描述页面的文件具有相同的路径和文件名,仅以后缀名进行区分。

因此output.filename中必须写为 [name].js,基于chunk id或者hash name的filename都会导致编译后的文件无法被小程序识别

webpack.config.js

  1. webpackconfig = {
  2. output: {
  3. filename: '[name].js', // 正确
  4. filename: '[id].js', // 错误。chunk id name
  5. filename: '[name].[chunkhash].js' // 错误。hash name
  6. }
  7. }

optimization

为了减少打包后app/page/component目录中的js文件体积。mpx提供了抽取公共依赖的能力。将共用的依赖进行统一抽取

通过optimization.runtimeChunkoptimization.splitChunks进行设置

webpack.config.js

  1. webpackConfig = {
  2. optimization: {
  3. runtimeChunk: {
  4. name: 'bundle'
  5. },
  6. splitChunks: {
  7. cacheGroups: {
  8. bundle: {
  9. chunks: 'all',
  10. name: 'bundle',
  11. minChunks: 2
  12. }
  13. }
  14. }
  15. }
  16. }