ソース マップを Azure Artifacts シンボル サーバーに発行して元のコードを安全にデバッグする

Web サーバーから返されるコンパイル済み、縮小済み、バンドルされた運用コードではなく、DevTools で元の開発ソース コードを安全に 確認して操作するには、Azure Artifacts シンボル サーバーによって提供されるソース マップを使用します。

ソース マップを Web サーバーに直接公開すると、元のソース コードが一般公開されます。 元のソース コードをパブリックに表示しないようにするには、ソース マップを Azure Artifacts シンボル サーバーに発行します。 この方法により、DevTools でソース マップを使用できます。運用環境の Web サイトをデバッグするときに、ソース マップを Web サーバーに公開せずに使用できます。

ソース マップは、コンパイル済みの運用コードを元の開発ソース ファイルにマップします。 DevTools では、コンパイルされたコードではなく、使い慣れた開発ソース ファイルを表示して操作できます。 DevTools でのソース マッピングとソース マップの使用の詳細については、「 デバッグのために、処理されたコードを元のソース コードにマップする」を参照してください。

概念

運用 Web サイトをデバッグするときにソース マップを DevTools で使用できるように、Azure Artifacts シンボル サーバーでソース マップのインデックスを作成する必要があります。

これを行うには、コンパイル時に x_microsoft_symbol_client_key string プロパティをソース マップに追加します。 このプロパティには、対応する元のソース ファイルの 256 ビット SHA-2 ハッシュ の小文字の 16 進値が含まれています。

DevTools は、コンパイルされた各ファイルに対してこのハッシュを計算し、ハッシュを使用して Azure Artifacts シンボル サーバーから正しいソース マップを取得できます。 ソース マップを安全に取得するために、DevTools では、指定した個人用アクセス トークンを使用して、Azure Artifacts シンボル サーバーに接続します。

手順 1: Azure DevOps の個人用アクセス トークンを生成する

ソース マップを Azure Artifacts シンボル サーバーに発行するには、 個人用アクセス トークン (または PAT) が必要です。 この PAT は、コードをコンパイルし、ソース マップを発行するときに、ビルド システムによって使用されます。

Azure DevOps で PAT を生成するには:

  1. に移動して、Azure DevOps organizationにサインインしますhttps://dev.azure.com/{yourorganization}

  2. Azure DevOps で、[ ユーザー設定>] [個人用アクセス トークン] の順に移動します。

    Azure DevOps の [ユーザー設定] メニューと [個人用アクセス トークン] コマンド

    [ 個人用アクセス トークン] ページが 表示されます。

    Azure DevOps の [個人用アクセス トークン] ページ

  3. [ 新しいトークン] をクリックします。 [ 新しい個人用アクセス トークンの作成 ] ダイアログが開きます。

    [新しい個人用アクセス トークンの作成] ダイアログで、[シンボル] の [読み取り & 書き込み] スコープが選択されています

  4. [ 名前 ] テキスト ボックスに、PAT の名前 ("ソース マップの発行" など) を入力します。

  5. [ 有効期限 ] セクションで、PAT の有効期限を入力します。

  6. [ スコープ ] セクションで、[ すべてのスコープを表示 ] をクリックしてセクションを展開します。

  7. [ シンボル ] セクションまで下にスクロールし、[ 読み取り & 書き込み ] チェック ボックスをオンにします。

  8. [作成] ボタンをクリックします。 [成功] ダイアログが表示されます。

    コピーする PAT を含む [Success!] ダイアログ

  9. [ クリップボードにコピー ] ボタンをクリックして PAT をコピーします。 トークンをコピーし、セキュリティで保護された場所に保存してください。 セキュリティのために、再び表示されることはありません。

PAT の詳細については、「 個人用アクセス トークンを使用する」を参照してください。

手順 2: スクリプトの SHA-256 ハッシュを計算し、ソース マップに追加する

アプリケーションのビルド プロセスの最後の手順で、発行するすべてのソース マップについて、ソース マップが対応する JavaScript ファイルの SHA-256 ハッシュを計算し、文字列プロパティを使用して x_microsoft_symbol_client_key ソース マップに追加する必要があります。

ビルド システムはアプリケーションによって異なるため、これを適用する明確な 1 つの方法はありません。 ただし、 Webpack 5 プラグインのサンプルを次に示します。このプラグインを使用している場合は、Webpack 構成に追加できます。

// file: webpack.plugin-symbols.js
// Copyright (C) Microsoft Corporation. All rights reserved.
// Licensed under the BSD 3-clause license.

const crypto = require('crypto');

module.exports = class PrepareSourceMapsForSymbolServerPlugin {
  /**
   * @param {import('webpack').Compiler} compiler
   * @returns {void}
   */
  apply(compiler) {
    compiler.hooks.emit.tap('PrepareSourceMapsForSymbolServerPlugin', (compilation) => {
      const files = Object.keys(compilation.assets);
      const sourceMaps = files.filter(v => v.endsWith('.map'));
      const sourceFilesAndMapsNames = sourceMaps.map(mapFileName => {
        const sourceFileName = mapFileName.substring(0, mapFileName.length - 4);
        return {
          sourceFileName,
          mapFileName,
        };
      });
      const sourceFiles = sourceFilesAndMapsNames.map(({ sourceFileName, mapFileName }) => {
        const sourceFile = compilation.assets[sourceFileName];
        const sourceFileBuffer = sourceFile.buffer();
        const hasher = crypto.createHash('sha256');
        hasher.write(sourceFileBuffer);
        const digest = hasher.digest();
        const sourceFileHash = digest.toString('hex');

        const sourceMapAsset = compilation.assets[mapFileName];
        const sourceMapSource = sourceMapAsset.source();
        const sourceMapContents = JSON.parse(sourceMapSource);
        sourceMapContents['x_microsoft_symbol_client_key'] = sourceFileHash;
        const rewrittenSourceMapContents = JSON.stringify(sourceMapContents);
        if (!sourceMapAsset.isBuffer()) {
          // Not a buffer -- write to the _value property
          sourceMapAsset._value = rewrittenSourceMapContents;
        } else {
          sourceMapAsset._valueAsBuffer = Buffer.from(rewrittenSourceMapContents, 'utf-8');
        }

        return {
          sourceFileName,
          mapFileName,
          sourceFileHash,
          sourceMapAsset,
        };
      });
    });
  }
};

その後、構成ファイルのセクションに plugins プラグインを webpack.config.js 追加できます。

const PrepareSourceMapsForSymbolServerPlugin = require('./webpack.plugin-symbols.js');

// ...

module.exports = (env, args) => {
  const mode = process.env.NODE_ENV || (env && env.NODE_ENV) || 'production';
  return {
    devtool: mode === 'production' ? 'hidden-source-map' : 'inline-source-map',
    resolve: {
      modules: [
        path.resolve('./node_modules'),
      ],
    },
    output: {
      publicPath: '/',
      filename: '[name].bundle.js',
      chunkFilename: '[name].chunk.js',
    },
    plugins: [
        // ... other plugins
        new PrepareSourceMapsForSymbolServerPlugin(),
    ]
  };
};

手順 3: ソース マップを Azure Artifacts シンボル サーバーに発行する

ソース マップを発行するには、次のいずれかのオプションを完了します。

Azure DevOps Pipelines を使用してソース マップを発行する

Azure DevOps にはパイプライン ビルド タスクが PublishSymbols@2 付属しています。 このタスクを使用して、ソース マップを Azure Artifacts シンボル サーバーに発行できます。

パラメーターを または SourceMapに設定してindexableFileFormats、このタスクをAll構成してください。

を使用してソース マップを発行する symbol.exe

シンボル サーバー チームは、 symbol.exe自動的に ダウンロードできる .NET Core アプリケーションを発行します。 を symbol.exeダウンロードした後、コマンドを実行して、ソース マップを Azure Artifacts シンボル サーバーに発行できます。

symbol publish
        -d {root directory containing your source maps}
        -n {a unique name for this job}
        -s {service URL, such as https://artifacts.dev.azure.com/contoso}
        --patAuthEnvVar {name of environment variable containing a PAT}
        --indexableFileFormats SourceMap

パラメーターは -n 一意である必要があることに注意してください。 失敗したジョブ名であっても、ジョブ名の繰り返しは拒否されます。

関連項目