# 从旧版本迁移至2.7

自 2.7 版本开始,Mpx 将编译构建流程基于 Webpack5 进行了全面的重构,优化解决了老的编译流程中存在的大量历史遗留问题,安全完整地支持了基于文件系统的持久化缓存,大幅提升了 Mpx 想的编译构建速度,以滴滴出行小程序为例,无缓存场景下相较 2.6 版本提速约 180%,有缓存场景下提速约 10 倍。

与此同时,Mpx 2.7 版本还带来了 rules 复用,完善的单元测试支持,独立分包构建,分包异步化等众多新特性。直接通过 @mpxjs/cli 创建的新项目就能够直接使用这些新特性,如果你对于编译构建没有太多定制化诉求,我们也推荐使用 @mpxjs/cli 新建项目,并将老项目中的 src 目录 copy 覆盖至新项目的方式进行迁移,这是一种成本最低的迁移方式。

如果你的老项目中已经对编译构建进行了高度的定制,本文将提供详细的迁移工作指引。

# 依赖升级

将下面列出的相关依赖升级至对应版本,如果有其他自行引入的 loader 也确保将其升级至 webpack5 兼容的版本:

{
  "dependencies": {
    "@mpxjs/api-proxy": "^2.7.1",
    "@mpxjs/core": "^2.7.1",
    "@mpxjs/fetch": "^2.7.1",
  },
  "devDependencies": {
    "@mpxjs/webpack-plugin": "^2.7.1",
    "webpack": "^5.64.4",
    "webpack-merge": "^5.8.0",
    "terser-webpack-plugin": "^5.2.5",
    "copy-webpack-plugin": "^9.0.1",
    "webpack-bundle-analyzer": "^4.5.0",
    "ts-loader": "^9.2.6",
    // eslint相关配置,按需安装
    "eslint": "^7.32.0",
    "eslint-config-standard": "^16.0.3",
    "eslint-plugin-html": "^6.2.0",
    "eslint-plugin-import": "^2.25.2",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^5.1.1",
    "eslint-webpack-plugin": "^3.1.0",
  }
}

# 开启持久化缓存

在 webpack 配置中添加以下配置项:

module.exports = {
  cache: {
    type: 'filesystem',
    // 声明构建配置,注意如果声明某个文件夹为构建配置,需要在文件夹下放置空的package.json文件,避免构建依赖收集时将主项目的依赖项视为构建依赖
    buildDependencies: {
      build: [resolve('build/')],
      config: [resolve('config/')]
    },
    cacheDirectory: resolve('.cache/')
  },
  snapshot: {
    // 如果希望修改node_modules下的文件时对应的缓存可以失效,可以将此处的配置改为 managedPaths: []
    managedPaths: [resolve('node_modules/')]
  },
}

# 修改rules

在 2.7 版本中,我们优化了 .mpx 文件中各个 block 应用 loader 的规则。

在之前的版本中,我们基本上使用内置的规则对 .mpx 中的 block 应用 loaders,如:对 <script> 应用 babel-loader,对 <style lang="stylus"> 应用 stylus-loader。这种方式的弊端主要在于用户无法便捷地自定义 block 的 loaders 应用规则,比如传入特定的 loaders 配置。

在 2.7 版本中,我们支持了构建时读取用户在 module.rules 中配置的规则来对 block 进行 loaders 应用, 例如:对于 <style lang="stylus"> 我们会对其应用用户在 rules 中对于 .stylus 文件 配置的 loaders,当用户没有在 block 中声明 lang 属性时,我们也会兜底使用不同区块默认的 lang 来进行 rules 匹配。

因此,相较于过去的版本,我们需要在 rules 中添加一些规则使得 .mpx 文件中的各类 block 都能得到正确的处理。

module.exports = {
  module: {
    rules: [
      // 新版本中rules规则对.mpx文件中的区块同样生效,在旧版本中.mpx文件中script会走内置的babel转义,但是新版当中只有在include范围内的.mpx文件才会走babel,但由于新版本中.mpx文件中的script会采用.mpx.js的格式来匹配rules,因此我们可以用如下include条件让其保持与旧版本一致的表现。
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [/\.mpx\.js/, resolve('src'), resolve('test'), resolve('node_modules/@mpxjs')]
      },
      // 如使用ts编码则需要添加本条rule
      {
        test: /\.ts$/,
        use: [
          'babel-loader',
          {
            loader: 'ts-loader',
            options: {
              appendTsSuffixTo: [/\.(mpx|vue)$/]
            }
          }
        ]
      },
      // 处理json区块
      {
        test: /\.json$/,
        resourceQuery: /asScript/,
        type: 'javascript/auto'
      },
      // 处理wxs
      {
        test: /\.(wxs|qs|sjs|qjs|jds|dds|filter\.js)$/,
        use: [
          MpxWebpackPlugin.wxsPreLoader()
        ],
        enforce: 'pre'
      },
      // 处理图像资源
      {
        test: /\.(png|jpe?g|gif|svg)$/,
        use: [
          MpxWebpackPlugin.urlLoader({
            name: 'img/[name][hash].[ext]'
          })
        ]
      },
      // 下面的rules输出小程序时需配置,如输出web需要修改为vue的相关rules,具体逻辑可以参考脚手架项目中build/getRules.js
      // mpx主loader
      {
        test: /\.mpx$/,
        use: MpxWebpackPlugin.loader(currentMpxLoaderConf)
      },
      // 如使用sass/less等其他预编译语言,自行修改test规则并用sass/less-loader替换stylus-loader
      {
        test: /\.styl(us)?$/,
        use: [
          MpxWebpackPlugin.wxssLoader(),
          'stylus-loader'
        ]
      },
      // 处理未使用预编译语言的style区块和独立样式文件
      {
        test: /\.(wxss|acss|css|qss|ttss|jxss|ddss)$/,
        use: MpxWebpackPlugin.wxssLoader()
      },
      // 处理未使用预编译语言的template区块和独立模板文件
      {
        test: /\.(wxml|axml|swan|qml|ttml|qxml|jxml|ddml)$/,
        use: MpxWebpackPlugin.wxmlLoader()
      }
    ]
  }
}

# entry配置修改

如果进行常规的小程序输出,无需关注。如进行插件输出或独立输出组件/页面等特殊场景,mpx 提供了辅助方法来生成对应的 entry request,示例如下:

module.exports = {
  entry:{
    // 输出plugin
    plugin: MpxWebpackPlugin.getPluginEntry('./plugin.json'),
    // 独立输出组件,相当于./list.mpx?isComponent,不过为了保障后续该配置不受框架内部query变动影响,建议使用辅助方法
    list: MpxWebpackPlugin.getComponentEntry('./list.mpx'),
    // 独立输出页面,相当于./index.mpx?isPage
    index: MpxWebpackPlugin.getPageEntry('./index.mpx')
  }
}

# MpxWebpackPlugin配置变更

  • 移除了forceDisableInject配置
  • nativeOptions更名为nativeConfig

上述的内容中只列举了一些和 mpx 高度相关的配置项变更,如果你的项目使用了特定的插件或者loader,请确保将其升级至兼容 webpack5 的版本。