簡體   English   中英

Webpack:無限循環和自動生成的文件

[英]Webpack: Infinite watch loop and auto-generated files

我有一個生成文件的腳本,稱之為auto.js 該文件包含一些動態生成的導入,並在 VueJS 項目中使用。

// auto.js

import { apple, strawberry, orange } from 'delicious-fruits';
import { carrot, cucumber, celery  } from 'delicious-vegetables';

在使用 Webpacks dev server時,如果任何項目文件發生更改,我的目標是讓此腳本重新生成我的auto.js文件,然后將其包含在重新編譯的項目中。

我已經把這個腳本變成了一個 Webpack 插件,我正在監聽watchRun編譯器鈎子 根據它的描述,這似乎是一個理想的鈎子:

在觸發新編譯后但在實際開始編譯之前在監視模式下執行插件。

class AutoGenerate {
  constructor(options) {
    this.options = options;
  }
  apply(compiler) {
    compiler.hooks.watchRun.tap('AutoGenerate', () => {
      generateFile()
    })
  }
}

function generateFile () {
  // generate auto.js and write to disk
}

我總是以無限循環的情況結束。 我嘗試通過使用各種生命周期事件(掛鈎)以及忽略自動生成的文件來解決問題。 當然,忽略它,這些更改不會包含在重新編譯的項目中。

const webpack = require('webpack');
const AutoGenerate = require("./auto.plugin");

module.exports = {
  configureWebpack: {
    plugins: [
      new webpack.WatchIgnorePlugin([/.*auto\.js/]),
      new AutoGenerate()
    ]
  }
}

我也嘗試過利用編譯,並在編譯中添加新資產。 雖然該過程不會出錯,但生成的資產不是最終編譯的一部分。

// auto.plugin.js

class AutoGenerate {

  static defaultOptions = {
    outputFile: 'auto.js',
  };

  constructor(options = {}) {
    this.options = { ...AutoGenerate.defaultOptions, ...options };
  }

  apply(compiler) {

    compiler.hooks.thisCompilation.tap('AutoGenerate', (compilation) => {

      const path = require("path")
      const filePath = path.resolve(__dirname, `src/plugins/${this.options.outputFile}`)
      const { RawSource } = require('webpack-sources')
      const fileContent = new RawSource(generateFile())

      compilation.emitAsset(
        filePath,
        fileContent
      )

    });

  }
}

function generateFile() {
  // generate file content & return as string
}

module.exports = { AutoGenerate };
// vue.config.js

const AutoGenerate = require("./auto.plugin");

module.exports = {
  configureWebpack: {
    plugins: [
      new AutoGenerate()
    ]
  }
}

如何觸發自動生成此文件的邏輯,同時將此文件作為任何重新編譯的一部分包含在內,同時避免無限循環?

我無法確定上述問題的直接解決方案。 但是,對於任何閱讀的人,我發現這可以通過使用名為before-build-webpack的 package 來實現,特別是通過包含watch-run觸發器。

// vue.config.js

const WebpackBeforeBuildPlugin = require('before-build-webpack')

module.exports = {
  configureWebpack: {
    plugins: [
      new WebpackBeforeBuildPlugin(function(stats, callback) {
        // ...
      }, ['run', 'watch-run'])
    ]
  }
}

暫無
暫無

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

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