web-dev-qa-db-ja.com

後者が両方を行うことができる場合、concatを使用してからuglifyを使用することが推奨されるのはなぜですか?

私はJSファイルを制作の準備を整えて連結し、uglifyにするための推奨事項を見続けています。

たとえば、 here は、Yeomanのうなり声の多いタスクです。

デフォルトでは、フローはconcat-> uglifyjsです。

UglifyJSは連結と縮小の両方を実行できることを考慮して、なぜ両方を同時に必要とするのでしょうか?

ありがとう。

38
Francisc

concatを実行してからuglifyを実行することと、単にuglifyを実行することとの間にパフォーマンスの違いがあるかどうかを確認するための基本的なテストの実行。

package.json

{
  "name": "grunt-concat-vs-uglify",
  "version": "0.0.1",
  "description": "A basic test to see if we can ditch concat and use only uglify for JS files.",
  "devDependencies": {
    "grunt": "^0.4.5",
    "grunt-contrib-concat": "^0.5.0",
    "grunt-contrib-uglify": "^0.6.0",
    "load-grunt-tasks": "^1.0.0",
    "time-grunt": "^1.0.0"
  }
}

Gruntfile.js

module.exports = function (grunt) {

    // Display the elapsed execution time of grunt tasks
    require('time-grunt')(grunt);
    // Load all grunt-* packages from package.json
    require('load-grunt-tasks')(grunt);

    grunt.initConfig({
        paths: {
            src: {
                js: 'src/**/*.js'
            },
            dest: {
                js: 'dist/main.js',
                jsMin: 'dist/main.min.js'
            }
        },
        concat: {
            js: {
                options: {
                    separator: ';'
                },
                src: '<%= paths.src.js %>',
                dest: '<%= paths.dest.js %>'
            }
        },
        uglify: {
            options: {
                compress: true,
                mangle: true,
                sourceMap: true
            },
            target: {
                src: '<%= paths.src.js %>',
                dest: '<%= paths.dest.jsMin %>'
            }
        }
    });

    grunt.registerTask('default', 'concat vs. uglify', function (concat) {
        // grunt default:true
        if (concat) {
            // Update the uglify dest to be the result of concat
            var dest = grunt.config('concat.js.dest');
            grunt.config('uglify.target.src', dest);

            grunt.task.run('concat');
        }

        // grunt default
        grunt.task.run('uglify');
    });
};

srcには、jQueryの非圧縮ソースを含む多数のJSファイルを配置し、数回コピーして、サブフォルダーに広げました。通常のサイト/アプリが通常持っているものよりもはるかに多く。

これらのファイルをすべて連結および圧縮するのにかかる時間は、どちらのシナリオでも基本的に同じです。
例外concatでもsourceMap: trueオプションを使用する場合(以下を参照)。

私のコンピューターで:

grunt default      : 6.2s (just uglify)
grunt default:true : 6s   (concat and uglify)

結果のmain.min.jsはどちらの場合も同じであることに注意してください。
また、uglifyは、ファイルを結合するときに適切なセパレーターの使用を自動的に処理します。

重要な唯一のケースは、sourceMap: trueconcatoptionsに追加する場合です。
これにより、main.js.mapの横にmain.jsファイルが作成され、結果は次のようになります。

grunt default      : 6.2s (just uglify)
grunt default:true : 13s  (concat and uglify)

しかし、実稼働サイトがminバージョンのみをロードする場合、このオプションは役に立ちません。

concatの前にuglifyを使用して、主要な短所を見つけました。
JSファイルの1つでエラーが発生すると、sourcemapは元のファイルではなく、連結されたmain.jsファイルにリンクします。 uglifyがすべての作業を行うのに対して、will元のファイルにリンクします。

更新:
uglifyソースマップをuglifyソースマップにリンクするconcatにさらに2つのオプションを追加できます。これにより、上記の「欠点」を処理できます。

    uglify: {
        options: {
            compress: true,
            mangle: true,
            sourceMap: true,
            sourceMapIncludeSources: true,
            sourceMapIn: '<%= paths.dest.js %>.map',
        },
        target: {
            src: '<%= paths.src.js %>',
            dest: '<%= paths.dest.jsMin %>'
        }
    }

しかし、それは非常に不要なようです。

結論

concatを使用している場合はJSファイルのuglifyを捨て、必要に応じて他の目的に使用できると結論付けるのは安全だと思います。

48
Alex Ilyaev

以下に引用する例では、ファイルは最初にconcatと連結され、次にuglifyによってuglified/minifiedされます。

{
  concat: {
    '.tmp/concat/js/app.js': [
      'app/js/app.js',
      'app/js/controllers/thing-controller.js',
      'app/js/models/thing-model.js',
      'app/js/views/thing-view.js'
    ]
  },
  uglifyjs: {
    'dist/js/app.js': ['.tmp/concat/js/app.js']
  }
}

同じことが次の方法で実現できます。

{
  uglifyjs: {
    'dist/js/app.js': [
      'app/js/app.js',
      'app/js/controllers/thing-controller.js',
      'app/js/models/thing-model.js',
      'app/js/views/thing-view.js'
    ]
  }
}

通常、タスクcleanは、一時フォルダー(この例ではconcat)に書き込むタスクの後に実行され、そのフォルダー内のコンテンツをすべて削除します。 cleanのようなタスクの前にcompassを実行して、ランダムに名前が付けられた画像スプライト(タスクが実行されるたびに新しく生成される)のようなものを削除したい人もいます。これにより、最も妄想的な人でも車輪が回転し続けます。

jshintを実行するタイミングと同様に、これはすべて設定とワークフローの問題です。コンパイル前に実行したい人もいれば、コンパイル済みファイルで実行したい人もいます。

信じられないほどのJavaScriptファイルを含む複雑なプロジェクト-またはますます多くのピアと貢献者がいる複雑なプロジェクトでは、物事をより読みやすく保守しやすくするために、uglifyの外部でファイルを連結することがあります。これがYeomanの-​​変換フローの選択の背後にある理由だと思います。

uglifyは、プロジェクトの構成によっては非常に遅くなる可能性があるため、最初にconcatと連結すると多少のゲインが生じる場合がありますが、確認する必要があります。

concatは、uglifyREADME.mdファイルが関係しています。

concat: {
  options: {
    separator: ';',
  }
}
27