打包兼容es5,问题排查及解决记录

2,955 阅读2分钟

最近做一个项目的兼容工作,要让代码能在"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36"上正常运行(用户常用浏览器版本)。通过在浏览器种输入以下代码可获取浏览器版本及内核。\

navigator.userAgent

运行环境及插件情况

windows 10
node v12.13.0 、 npm 6.12.0
vue/cli 3、webpack 3.12 、babel 7

修改配置

babel官网对babel7配置做了如下的解释

Babel has had issues previously with handling node_modules, symlinks, and monorepos. We've made some changes to account for this: Babel will stop lookup at the package.json boundary instead of looking up the chain. For monorepos we have added a new babel.config.js file that centralizes our config across all the packages (alternatively you could make a config per package). In 7.1, we've introduced a rootMode option for further lookup if necessary

  • 将.babelrc替换成babel.config.js
module.exports = {
    presets: [
        '@vue/babel-preset-app'
    ],
};
  • 查看webpacke.base.config
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.m?js(\?.*)?$/i,
        loader: 'babel-loader',
        include: [
          resolve('src'), resolve('test'),  resolve('static')
        ]
      },
    ...
    ]
  }

查看打包情况,发现仍有es6语法

打包之后,排查app.js仍有es6的语法,比如const、let、=>,vendor.js里面也有。

排查es6语法出现的上下文,判断未转换语法位置

1、配置webpack,引入NamedModulesPlugin(当开启 HMR 的时候使用该插件会显示模块的相对路径,建议用于开发环境。)
2、关闭HashedModuleIdsPlugin

    // new webpack.HashedModuleIdsPlugin(),
    new webpack.NamedModulesPlugin(),

打包之后发现const、let在'node_modules/vue-runtime-helpers', 'node_modules/v-contextmenu'这两个模块中。

查看引入第三方库方式

  • 为啥会引入.mjs而不是.js文件呢?(ES模块是扩展名为.mjs的文件的目标。)

因为入口文件main.js是使用的ES模块引入的。

import Vue from 'vue'
import App from './App'
import router from './router'
  • 查看第三方库的代码
    node_modules文件夹下的vue-runtime-helpers的dist/index.js确实是es5的代码,但是dist/index.mjs却是es6的代码。打包引入的是.mjs文件
    使用别名可以解决这一问题,配置如下:(如果有更好的方法也欢迎各位指出)
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue-runtime-helpers': resolve('node_modules/vue-runtime-helpers/dist/index.js'),
    }
  },

再次打包之后,发现vue-runtime-helpers这一块的代码已经没有es6的语法了,但是v-contextmenu模块依旧是es6的代码,经查看后发现node_modules文件夹下的v-contextmenu的dist/index.js和dist/index.mjs都是es6的语法。

在这个第三方库的issue种发现存在这个问题,并且有解决方案
github.com/heynext/v-c…
通过降低该版本,解决了这一问题。