通过自定义webpack插件实现react-router不兼容的问题

164 阅读1分钟

在自己搭建的组件库中,添加了一个router路由拦截的组件,依赖的router版本是v4,但组件库网站使用了bisheng,但bisheng里使用的react-router是另一种规范的,为了能引用到这种规范下的文件,在bisheng的配置文件中,它指定了一个别名:

    config.resolve.alias = {
      // ...
      'react-router': 'react-router/umd/ReactRouter',
    };

但是,这样一来,在开发服务器中,自己编写的路由拦截组件在import react-router的时候也就引到这个地方来了,但我们自己编写组件通常是遵循esm规范的,所以导致报错

最后,通过编写webpack插件,来将两种场景区分开来

var assign = require('object-assign');
var forEachBail = require('enhanced-resolve/lib/forEachBail');

module.exports = function (options = {}) {
  return {
    apply: doApply.bind(this, options)
  };
};

function doApply(options = {}, resolver) {
  var target = resolver.ensureHook("resolve");
  resolver.getHook("before-resolve")
    .tapAsync("ModuleResolveWebpackPlugin", (request, resolveContext, callback) => {
      var attempts = [];
      Object.keys(options).forEach(module => {
        Object.keys(options[module]).forEach(dep => {
          const reg = new RegExp(dep + '$');
          if (request.path.includes(module) && reg.test(request.request)) {
            var obj = assign({}, request, {
              request: options[module][dep]
            });
            attempts.push(obj);
          }
        })
      })
      if (attempts.length) {
        forEachBail(
          attempts,
          function (obj, innerCallback) {
            resolver.doResolve(target, obj, " using " + request.request, resolveContext, innerCallback);
          },
          callback
        );
      } else {
        return callback();
      }
    });
}

webpack中使用方式:

    config.resolve.alias = {
      // ...
      // 'react-router': 'react-router/umd/ReactRouter',
    };
    config.resolve.plugins = [
      new ModuleResolveWebpackPlugin({
        'bisheng': {
          'react-router': 'react-router/umd/ReactRouter'
        }
      })
    ];