6

我正在编写一个 Webpack 插件,它应该用 Webpack 生成的 CSS 文件列表替换部分 JS 代码。成像这个 JS 代码:

ReactWebComponent.create(<App />, 'react-web-component', { injectReactWebComponent: true });

我想injectReactWebComponent: true

injectReactWebComponent: '<link href="static/css/main.cacbacc7.css" rel="stylesheet">'

而那个链接标签是由 Webpack 生成的文件。

我的(工作类型)代码如下:

ReactWebComponent.prototype.apply = function(compiler) {
  compiler.plugin('emit', function(compilation, callback) {
    const cssFiles = Object.keys(compilation.assets)
        .filter(fileName => /\.css$/.test(fileName));

    const jsFiles = Object.keys(compilation.assets)
        .filter(fileName => /\.js$/.test(fileName));

    const cssLinkTagsAsString = cssFiles
        .map(fileName => `<link href="${fileName}" rel="stylesheet">`)
        .join('');

    jsFiles.forEach(fileName => {
      compilation.assets[fileName].children.forEach(child => {
        if (child._value) {
          child._value = child._value.replace(/injectReactWebComponent\s*:\s*true/g, `injectReactWebComponent: \'${cssLinkTagsAsString}\'`);
        }
      });
    });

    callback();
  });
};

module.exports = ReactWebComponent;

看我做的那一行

child._value = child._value.replace(...)

我直截了当地重写了来源。

但这似乎不适合我。看来我正在转换的代码已经生成,不应该再转换了。我也很确定我用这个打破了源地图。

所以我想知道,什么是实现我正在做的事情的合适方法?

我猜测我应该使用转换部分loader,但是加载器不知道生成的文件名,或者是吗?

任何帮助,将不胜感激!

4

1 回答 1

5

看起来这种事情很简单,可以由加载器处理,其中有多个(有些比其他更好):

https://www.npmjs.com/package/string-replace-loader

https://www.npmjs.com/package/regexp-replace-loader

https://www.npmjs.com/package/replace-loader

如果您想制作自己的插件来执行此操作(我刚刚完成了一些比正则表达式替换更复杂的操作),我可以将我的解决方案从以下三个页面拼凑在一起:

https://github.com/webpack/webpack/blob/master/lib/BannerPlugin.js

https://webpack.js.org/api/plugins/compilation/#optimize-chunk-assets-chunks-chunk-async

https://github.com/webpack/webpack-sources

于 2017-09-15T01:28:44.983 回答