代码之家  ›  专栏  ›  技术社区  ›  Ryan Wheale

自定义网页解析器,用于SystemJS风格的导入!带加载器

  •  0
  • Ryan Wheale  · 技术社区  · 7 年前

    我有一个使用SystemJS的项目-这无法改变。我们也在使用故事书,它使用网页-这也不能改变。到目前为止,这两个人打得很好。然而,我有一个模块,它将文件加载为纯文本并对其进行解析:

    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'
    

    我遵循了几个创建自定义解析器的示例( here here ),但没有一个有效负载包含重建请求对象所需的所有数据。有什么方法可以连接到网页包吗 在模块解析的早期 为了实现我的目标?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Ryan Wheale    7 年前

    我能够使用自定义加载程序来实现我的目标。这并不理想,但解析逻辑相当简单,可以随着时间的推移变得更强。使用此策略,我只能将其应用于项目文件(任何文件) 在里面 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;
    };