chenshuai2144 / umi-plugin-antd-theme

🎨 Best theme plugin
https://preview.pro.ant.design/
MIT License
85 stars 29 forks source link

feat: less re-render should be called only with .less file change #24

Closed leftstick closed 3 years ago

leftstick commented 4 years ago

现在每次有文件变更的时候都会触发一次less 的re-render。实在是太慢了。

所以我想,

  1. 找出本次变更的文件(目前的策略有点水,但聊胜于无)
  2. 如果变更文件是应用里的.less文件,则触发less 的re-render
  3. 如果变更文件不是.less文件,ignore re-render的过程
ganshuai commented 4 years ago

我的思路跟你一样的,不过我还简单判定了一下less文件的内容,如果里面没有使用less的变量,也跳过re-render。 这是index.ts中更改的代码


  ...
  // 编译完成之后
  api.onBuildComplete(({ err }) => {
    ...
  }
  class WebpackPluginForUmiPluginAntdTheme {
    apply(compiler: Compiler) {
      compiler.hooks.watchRun.tapAsync(
        'WebpackPluginForUmiPluginAntdTheme',
        function(_compiler, done) {
          const watchFileSystem = (_compiler as any).watchFileSystem;
          const watcher =
            watchFileSystem.watcher || watchFileSystem.wfs.watcher;
          const lessFiles = Object.keys(watcher.mtimes).filter(fileName =>
            /\.less\b/.test(fileName),
          );
          isNeedBuildCss =
            isFirstCompileFinished &&
            lessFiles.length > 0 &&
            !isNotUseLessVariable(lessFiles);
          done();
        },
      );
    }
  }

  api.chainWebpack({
    fn(initialValue) {
      initialValue
        .plugin('WebpackPluginForUmiPluginAntdTheme')
        .use(WebpackPluginForUmiPluginAntdTheme);
      return initialValue;
    },
  });

  // dev 之后
  api.onDevCompileDone(() => {
    isFirstCompileFinished = true;

    if (!isNeedBuildCss) {
      api.logger.info(
        '不是less文件或者更改的文件中未使用less变量,跳过less主题编译',
      );
      return;
    }
   ...
}
function isNotUseLessVariable(fileNames: string[] = []) {
  return fileNames.every(fileName => {
    const content = readFileSync(fileName).toString();
    return !/\@\{/.test(content);
  });
}