我如何混淆 Ember 中的 Javascript?

How do I obfuscate Javascript in Ember?

有谁知道如何在 Ember 中使用 javascript-obfuscator(或类似的)?

我想它需要在 ember-cli-build.js 中调用,但我不知道在哪里以及如何调用。

提前感谢您的帮助:)

我认为对此没有真正直接的答案。如果您在 embroider, then all your Javascript will be handled by webpack, so you could try using webpack-obfuscator 上 运行 -- 在您的 ember-cli-build.js 中类似于

return require('@embroider/compat').compatBuild(app, Webpack, {
  plugins: [
    new WebpackObfuscator(/*whatever args*/)
  ],
  rules: [
    {
      test: /\.js$/,
      enforce: 'post',
      use: { 
        loader: WebpackObfuscator.loader, 
      }
    }
  ]
});

我知道的其他选择是编写西兰花插件。您所做的与 ember-cli-terser 所做的类似 - post-process Javascript files before they get concatenated together - 因此您可以将其用作参考。

您需要编写一个真正执行转换的西兰花插件(模拟是 broccoli-terser-sourcemap) and an Ember addon to hook it into ember-cli's build pipeline (the analog is ember-cli-terser)。

西兰花插件

看看 broccoli-terser-sourcemapindex.js,它只有 114 行代码,我认为你可以将它改编成这样:

module.exports = class TerserWriter extends Plugin {
  constructor(_inputNodes, options = {}) {
    let inputNodes = Array.isArray(_inputNodes) ? _inputNodes : [_inputNodes];

    super(inputNodes, {
      name: options.name,
      annotation: options.annotation,
      needsCache: false,
    });

    this.options = defaults(options, {
      obfuscator: {},
    });

    let exclude = this.options.exclude;
    if (Array.isArray(exclude)) {
      this.excludes = new MatcherCollection(exclude);
    } else {
      this.excludes = MatchNothing;
    }
  }

  async build() {
    let pendingWork = [];

    this.inputPaths.forEach(inputPath => {
      walkSync(inputPath).forEach(relativePath => {
        if (relativePath.slice(-1) === '/') {
          return;
        }
        let inFile = path.join(inputPath, relativePath);
        let outFile = path.join(this.outputPath, relativePath);

        fs.mkdirSync(path.dirname(outFile), { recursive: true });

        if (this._isJSExt(relativePath) && !this.excludes.match(relativePath)) {
          pendingWork.push(() => this.processFile(inFile, outFile, relativePath, this.outputPath));
        } else {
          symlinkOrCopy.sync(inFile, outFile);
        }
      });
    });

    for (let fn of pendingWork) {
      await fn();
    }
  }

  _isJSExt(relativePath) {
    return relativePath.slice(-3) === '.js' || relativePath.slice(-4) === '.mjs';
  }

  async processFile(inFile, outFile, relativePath, outDir) {
    let input = await readFile(inFile).toString();
    let result = obfuscate(input, this.options.obfuscator);
    await writeFile(outFile, result.getObfuscatedCode());
  }
};

你也可以像 broccoli-terser-sourcemaps 那样做 worker pooling,如果你关心源映射,你也需要处理它们,但是 broccoli-terser-sourcemaps 就是这样做的,所以你可以作为参考。

ember-cli 插件

ember-cli-terser 的代码更少——看看它的 index.js,你可以将它改编成类似

的代码
'use strict';

module.exports = {
  name: require('./package').name,

  included(app) {
    this._super.included.apply(this, arguments);

    let defaultOptions = {
      enabled: app.env === 'production',

      obfuscator: {
        // default `javascript-obfuscator` options
      },
    };

    let addonOptions = app.options['ember-cli-obfuscator'];

    this._obfuscatorOptions = Object.assign({}, defaultOptions, addonOptions);
  },

  postprocessTree(type, tree) {
    if (this._obfuscatorOptions.enabled === true && type === 'all') {
      // Import the plugin code above
      const Obfuscator = require('./broccoli-obfuscator');

      return new Obfuscator(tree, this._obfuscatorOptions);
    } else {
      return tree;
    }
  }
};

然后你必须在你的应用程序中安装上面的插件(它可能是一个 in-repo 插件),它应该做它的事情!

这肯定需要做一些工作,但您所做的与 ember-cli-terser 所做的非常相似,只是使用 obfuscator API 而不是 [=26] =] API,你的起点真的很好。

但是,如果 embroider 是您的选择,我肯定会先尝试这条路线,因为它可能只是一个配置问题,而不是编写一堆代码。