簡體   English   中英

Webpack插件:如何動態地將模塊添加到主Chunk?

[英]Webpack Plugin: How to add dynamically a Module to the main Chunk?

我正在開發一個Webpack插件,它基本上在塊中查找css資源,當它找到這樣的資產時,在它上面應用一些返回2個輸出的postCSS插件,應該繼續使用Extract-Text-Plugin另一個輸出應該成為中的一個新模塊 ,它在運行時將它注入頭部。

我沒有設法實現的唯一部分是在現有 Chunk中創建新模塊的部分。 有一些指示/想法?

我設法創建了一個新的塊 ,但沒有webpack包裝器,這意味着我無法支持HMR用於那塊css並且懶得加載它。

class ExtractTPAStylePlugin {
  constructor(options) {
    this._options = Object.assign({
      pattern: [
        /"\w+\([^\)]+\)"/
      ]
    }, options);
  }

  extract(compilation, chunks) {
    const promises = [];

    chunks.forEach((chunk) => {
      promises.push(
        chunk.files
          .filter(fileName => fileName.endsWith('.css'))
          .map(file => postcss([extractStyles(this._options)])
            .process(compilation.assets[file].source(), {from: file, to: file})
            .then((result) => {
              compilation.assets[file] = new RawSource(result.css);

              const filename = file.replace('.css', fileSuffix);
              const newChunk = new Chunk(filename);
              newChunk.files = [filename];
              newChunk.ids = [];
              compilation.chunks.push(newChunk);
              const extractedStyles = `(${addStylesTemplate})()`
                .replace('__CSS__', JSON.stringify(result.extracted))
                .replace('__ID__', file);
              compilation.assets[filename] = new OriginalSource(extractedStyles);
            }))
      );
    });

    return Promise.all(promises);
  }

  apply(compiler) {
    compiler.plugin('compilation', (compilation) => {
      compilation.plugin('optimize-chunk-assets', (chunks, callback) => {
        this.extract(compilation, chunks)
          .then(() => callback())
          .catch(callback);
      });
    });
  }
}

module.exports = ExtractTPAStylePlugin;

好吧,所以我設法從幾個插件中收集了一些代碼片段,而獲勝的解決方案是將一個加載器注入到一些假的導入文件中,在該加載器中將整個js代碼加載到主包中,並放置一些占位符來自optimize-chunk-assets階段的結果。

之后,在optimize-chunk-assets ,您可以找到相關的塊,並使用ReplaceSource來查找和替換占位符。

為了獲得靈感,您可以查看該插件

或許有更多方法可以做到這一點。

我發現一種方便的方法是創建一個自定義的NormalModuleFactory插件並用編譯器掛鈎。

插件接收模塊請求和上下文(從哪里導入的內容)。 有了它,您可以匹配請求並返回您的模塊源。 簡化后,它看起來像:

class CustomModuleFactoryPlugin {
  apply (normalModuleFactory) {

    // Tap in the factory hook.
    normalModuleFactory.hooks.factory.tap(
      'CustomModuleFactoryPlugin',
      factory => (data, cb) => {
        const { context } = data
        const { request } = data.dependencies[0]

        if (path.join(context, request).contains('/something/you/expect') {
          return cb(null, new RawSource('Success!'))
        }

        return factory(data, cb)
      }
    )
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM