用于SystemJS样式导入的自定义Webpack解析器!与装载机

时间:2017-11-18 17:52:44

标签: webpack systemjs dependency-resolver

我有一个使用SystemJS的项目 - 这不能改变。我们也在使用使用WebPack的StoryBooks - 这也无法改变。到目前为止,两人相处得非常好。但是,我有一个模块,它将文件作为纯文本加载并解析它们:

import stuff from './some-module!systemjs-plugin-text';
parseStuff(stuff);

如果我的项目使用的是WebPack,则上面的代码如下所示:

import stuff from 'raw-loader!./some-module';
parseStuff(stuff);

由于SystemJS是"主要"模块加载器,我希望所有应用程序代码都以SystemJS为中心。我想为webpack编写一个自定义解析器来进行SystemJS样式的导入和"翻转"他们(可以这么说)。代码如下所示:

const moduleMap = {
  'systemjs-plugin-text': 'raw-loader'
};
const formatModuleIdForWebPack (systemjsId) {
  const webpackId = systemjsId.split('!').reverse();
  webpackId[0] = moduleMap[ webpackId[0] ] || webpackId[0];
  return webpackId.join('!');
}
formatModuleIdForWebPack('./some-module!systemjs-plugin-text');
//-> 'raw-loader!./some-module'

我已经按照几个示例创建了自定义解析程序(herehere),但没有一个有效负载包含重构请求对象所需的所有数据。有没有办法在模块解析的早期挂钩到WebPack 以实现我的目标?

1 个答案:

答案 0 :(得分:1)

我能够使用自定义加载程序来实现我的目标。这并不理想,但解析逻辑非常简单,可以随着时间的推移变得更强大。使用此策略,我只能将其应用于项目文件(node_modules中的任何)。

  {
    test: /\.js$/,
    loader: path.resolve('systemjs-loader.js'),
    exclude: [
      path.resolve('node_modules')
    ],
    options: {
      loaderMap: {
        'systemjs-plugin-text': 'raw-loader'
      }
    }
  }

...和加载程序代码:

const { getOptions } = require('loader-utils');
const escapeRegexp = require('escape-string-regexp');
/**
 * Replaces systemjs-style loader syntax with webpack-style:
 * 
 *   ./some-module!systemjs-plugin  ->  webpack-plugin!./some-module
 */
module.exports = function (source) {
  const options = getOptions(this);
  const map = options.loaderMap;
  if (!map) {
    throw new Error('There is no need to use the systemjs loader without providing a `loaderMap`');
  }
  Object.keys(map).forEach(loader => {
    // indexOf should be faster than regex.test
    if (source.indexOf(loader) !== -1) {
      const exp = new RegExp(`(['"])([^!]+)!${escapeRegexp(loader)}['"]`, 'g');
      source = source.replace(exp, `$1${map[loader]}!$2$1`);
    }
  });
  return source;
};