前言

距离 Vite 发布已经有几个年头,但由于长期维护历史遗留项目,鲜有机会去尝试使用其提升开发效率。

传闻 Vite 较于 Webpack 有将近十倍的性能提升,考虑到开发机的性能难以支撑数千个模块编译的即时响应,以及项目后续对于 Electron 的适配,便决定使用 Vite 来替代原有组件。

但项目迁移途中并不顺利,因为DataV模块迁移后遇到了以下错误:

Uncaught SyntaxError: The requested module '/node_modules/@jiaminghi/c-render/lib/index.js?v=46828e67' does not provide an export named 'default' (at main.vue:8:1)

DataV 是一个基于 Vue2 的大屏数据展示组件库,本文将围绕该问题进行解决。

问题分析

查看文件node_modules/@jiaminghi/c-render/lib/index.js可知文件是由node_modules/@jiaminghi/c-render/src/index.js编译得到。

  • 点击展开

      "use strict";  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");  Object.defineProperty(exports, "__esModule", {
        value: true  });  Object.defineProperty(exports, "CRender", {
        enumerable: true,    get: function get() {
          return _crender["default"];    }
      });  Object.defineProperty(exports, "extendNewGraph", {
        enumerable: true,    get: function get() {
          return _graphs.extendNewGraph;    }
      });  exports["default"] = void 0;  var _crender = _interopRequireDefault(require("./class/crender.class"));  var _graphs = require("./config/graphs");  var _default = _crender["default"];  exports["default"] = _default;
    

或许是 Vite 不支持加载编译后的模块,项目中其它使用类似export default的代码都工作正常。

于是便尝试使用 Vite 加载node_modules/@jiaminghi/c-render/src/index.js文件。

  • 点击展开

      import CRender from './class/crender.class'  import { extendNewGraph } from './config/graphs'  export {
      CRender,  extendNewGraph
      }
      export default CRender
    

结果是成功的,但 DataV 包中几乎整个项目都是加载编译后的代码,为了解决这个问题,便需要了解 Vite 的解析机制了。

解决方案

Vite 可以对引入包的路径进行自定义解析,详情参见 ResolveAlias

通常项目会定义 “@” -> “src” 的 Alias 来便于组件的加载。

那么,利用这个特性编写以下解析配置,便可解决 DataV 在 Vite 中无法使用的问题。

import {defineConfig} from 'vite';import vue from '@vitejs/plugin-vue2'// https://vitejs.dev/configexport default defineConfig({
  resolve: {
    alias: [
      {
        find: /@jiaminghi\/.+/, replacement: path => {
          path = path.replace('lib', 'src')
          if (/^[^/]+$/.test(path))
            path = `${path}/src`          else if (/\.css$/.test(path))
            path = path.replace('src/components', 'lib/components')
          return path
        }
      },    ]
  },  plugins: [vue()],});
  • 需要执行以下命令安装依赖包,以使用上述解决方案。
npm install @vitejs/plugin-vue2 less -D