web-dev-qa-db-ja.com

相対パスで動作するようにgrunt-useminを構成するにはどうすればよいですか

generator-webapp に基づいて構築したyeoman-generatorに支えられた不快なプロジェクトがあります。何かの助けになれば、 GitHub で見つけることができます=

グラントプロジェクトは grunt-usemin タスクを使用します。

私のプロジェクトでは、多言語のWebサイトを構築する必要があり、物事をきれいに保つために、ある言語で書かれたすべてのページを、その言語の2文字のショートコードの後に​​フォルダー名に入れることにしました。

| project/
|--dist/
|----en/
|------index.html
|------404.html
|------...
|----fr/
|------index.html
|------404.html
|------...

ファイルはハンドルバーテンプレートから作成され、 assemble で処理されます。レイアウトには、次のようなuseminのビルディングブロックがあります。

<!-- build:css(.tmp) styles/main.css -->
<link rel="stylesheet" href="../styles/main.css">
<!-- endbuild -->
<!-- build:js scripts/vendor/modernizr.js -->
<script src="../bower_components/modernizr/modernizr.js"></script>
<!-- endbuild -->

完璧な世界ではこれは

<link rel="stylesheet" href="../styles/main.css">
<script src="../scripts/vendor/modernizr.js"></script>

しかし代わりに

<link rel="stylesheet" href="styles/main.css">
<script src="scripts/vendor/modernizr.js"></script>

これは私の場合、理想的とは言えません。 Gruntfile.jsの関連部分は次のようになります

    useminPrepare: {
        options: {
            dest: '<%= yeoman.dist %>'
        },
        html: [
            '<%= yeoman.app %>/fr/{,*/}*.html',
            '<%= yeoman.app %>/en/{,*/}*.html'
        ]
    },
    usemin: {
        options: {
            dirs: ['<%= yeoman.dist %>']
        },
        html: [
            '<%= yeoman.dist %>/fr/{,*/}*.html',
            '<%= yeoman.dist %>/en/{,*/}*.html'
        ],
        css: ['<%= yeoman.dist %>/styles/{,*/}*.css']
    }

basedir オプションを<%= yeoman.dist %>に設定し、ビルドブロックを

<!-- build:css(.tmp) ../styles/main.css -->
<link rel="stylesheet" href="../styles/main.css">
<!-- endbuild -->
<!-- build:js ../scripts/vendor/modernizr.js -->
<script src="../bower_components/modernizr/modernizr.js"></script>
<!-- endbuild -->

しかし、残念ながら適切な出力を得ることができませんでした。

より具体的には、最初の1つは何も変更せず、2番目の1つはscriptsおよびstylesフォルダーが階層の1レベル上に出力されました

| project/
|--app/
|--dist/
|--styles/
|--scripts/

の代わりに

| project/
|--app/
|--dist/
|----styles/
|----scripts/

誰かが偶然何をすべきか知っていますか?それはかなり単純なユースケースのようですが、Google、GitHub、またはSOを介して必要なヘルプを見つけることができませんでした...

21

私はあなたがこのようにして必要なものを達成できると信じています:

HTMLファイル:

    <!-- build:css styles/main.css -->
    <link href='../styles/css/style.css' rel='stylesheet' type='text/css'>
    <link href='../styles/css/responsive.css' rel='stylesheet' type='text/css'>

    <link href="../styles/css/skins/welld.css" rel='stylesheet' type='text/css' id="skin-file">
    <!-- endbuild -->

Gruntfile.js

        useminPrepare: {
            options: {
                dest: '<%= yeoman.dist %>/'
            },
            html: ['<%= yeoman.app %>/snippets/head.html','<%= yeoman.app %>/snippets/tail.html']
        },
        usemin: {
            options: {
                dirs: ['<%= yeoman.dist %>/'],
                blockReplacements: {
                    css: function (block) {
                        return '<link rel="stylesheet" href="../' + block.dest + '"/>';
                    },
                    js: function (block) {
                        return '<script src="../' + block.dest + '"></script>';
                    }
                }
            },
            html: ['<%= yeoman.dist %>/{,*/}*.html'],
            css: ['<%= yeoman.dist %>/styles/{,*/}*.css']
        }

重要な解決策は、useminタスクのblockReplacementsオプションにあります。基本的に、タスクはファイルを<%= yeoman.dist%>/styles/main.cssの下に配置し、HTMLは<%= yeoman.dist%>/en/somefileinEnglish.htmlおよび 'stylesのすべてのインスタンスの下に配置しますこのファイルの/main.css」は「../styles/main.css」に置き換えられ、正しい相対パスが追加されます。

追加のヒントとして、多言語のWebサイトを構築している場合は、構築中にファイルを翻訳する grunt-i18n を検討することをお勧めします。そのため、言語ごとに異なるhtmlファイルを維持する必要はありません。 。

4
Luca Camerini

私は自分のGrunt足場を構築していたが、この問題に不満を感じていた。あなたと共有したい回避策を作成することができました。

私自身の例を使用して、彼の問題の背後にある理由と、私がどうやって対処したかを説明したいと思います。私のディレクトリ構造は次のとおりだとしましょう:

| in/
+---- pages/
|    +---- login.html
+---- js/
|    +---- s1.js
|    +---- s2.js
+---- index.html
| out/
| Gruntfile.js

ここで、in/はすべてのソースファイルが存在する場所であり、out/はすべての出力ファイルが保存されるdestディレクトリです。 s1.jslogin.htmlにインポートする場合、次のように記述します。

<!-- build:js ../js/login.js -->
<script src="../js/s1.js"></script>
<!-- endbuild -->

ここでは、useminブロックが単純な文字列置換を実行するため、出力パスは出力ファイルをリンクしたい場所に正確に一致する必要があります。この問題は、login.jsout/js/login.jsで着陸する代わりに、useminPrepareがjs/login.jsで着陸する場合に発生します。これの背後にある理由は、useminPrepareは、destout)と出力パス(../js/login.js)の間のパス結合を実行するだけですが、HTMLファイルの場所に関してパス結合を実行する必要があるためです。 。

この問題を回避するには、out/pagesが見つかった場所を尊重するdestlogin.htmlに設定すると、問題なく機能することを確認してください。ただし、index.htmljs/s2.jsを同様の方法でインポートすると、失敗することに注意してください。そのため、これを回避するには、index.htmlを使用したdest: "out"のuseminPrepareターゲットを1つ作成し、login.htmlを使用したdest: "out/pages"の別のターゲットを作成する必要があります。したがって、私のuseminPrepare設定は次のようになります。

"useminPrepare": {
    t1: {
        dest: "out",
        files: [{src: ["in/*.html"]}],
        ...
    },
    t2: {
        dest: "out/pages",
        files: [{src: ["in/pages/*.html"]],
        ....
    }
}

すべてのターゲットを実行する必要があります。今、あなたはおそらく言うでしょう。他のサブディレクトリの下にさらに多くのHTMLファイルがある場合はどうなりますか?つまり、HTMLファイルが見つかったディレクトリごとに1つのターゲットを作成する必要があるということですか。これはお尻の痛みと愚かです。そうです!同意する。だから私は助けるために非常に特別なうなり声タスクを書きました。私はそれを seminPreparePrepare と呼びますIS愚かなので、私はわざと愚かに名前を付けました。私は、useminの人々がこの問題を修正した1日あたりに、この作業を解消したいと思っています。その名前が示すように、useminPreparePrepareはuseminPrepareの構成を準備します。独自の構成はuseminPrepareをミラーリングします(実際、ほとんどの構成は単純にコピーされます)が、1つの例外があります。すべてのソースファイルが存在するソースルートディレクトリを指すsrcプロパティを追加して、ソースルートとHTMLファイル間の相対パスを把握できるようにする必要があります。それは本質的に私が上で述べたものを実行します。さらに、ステージングディレクトリに対しても同じことを行うので、ステージングファイルがステージングディレクトリから壊れることはありません。 useminPreparePrepareに複数のターゲットを設定することもできます。実行したターゲットのオプションがコピーされます。

この回避策を使用するには、最初にuseminPreparePrepareをインポートする必要があります。 npmには入れなかったので、コピーして貼り付ける必要があります。私は気にしません。次に、useminPrepare構成の名前をuseminPreparePrepareに変更し、srcプロパティを追加します。上記の例では、src: "in"です。次に、通常使用するターゲットでuseminPreparePrepareを実行し、ターゲットを指定せずにすぐにuseminPrepareを実行して、すべてのターゲットが実行されるようにする必要があります。上記の例では、Gruntの構成は次のようになります。

"useminPreparePrepare": {
    html: "in/**/*.html",   // All HTML files under in/ and its subdirectories.
    options: {
        src: "in",
        dest: "out",
        ....
    }
},
"copy": {
    html: { // Copies all HTML files from in/ to out/ preserving their relative paths.
        files: [{
                expand: true,
                cwd: "in",
                src: ["**/*.html"],
                dest: "out"
            }
        ]
    }
},
"usemin": {
    html: "out/**/*.html",  // Process all HTML files under out/ and its subdirectories.
    ...
}

上記の設定は、すべてのHTMLファイルをソースディレクトリの下に再帰的に含めるのに十分なほど単純であることがわかります。 useminPrepareのように見える間、useminPreparePrepareはすべての愚かな回避策を処理します。

これが役に立てば幸いです!

3
initialxy

私の解決策は、手動でgrunt-useminプラグインを変更することでした。

お気に入りのテキストエディタでnode_modules/grunt-usemin/fileprocessor.jsを開きます。 152行目あたりのどこかが見つかります:

if (assetSearchPath && assetSearchPath.length !== 0) {
  this.file.searchPath = assetSearchPath;
}

そしてそれを次のように置き換えます:

if (assetSearchPath && assetSearchPath.length !== 0) {
  this.file.searchPath.splice(0, 0, assetSearchPath);
}

デフォルトでは、this.file.searchPathは現在のファイルへの絶対パスを含む配列です。 ['dist']で上書きしても意味がありません。配列の先頭に「dist」を追加することをお勧めします。このように、「dist」ディレクトリにアイテムが見つからない場合、パスが相対パスであるか間違っていると結論付けられる可能性があります。したがって、searchPath配列の2番目の値を使用してファイルを検索し、それが相対パスであるかどうかを確認します。

1

以下に示すように、複数のターゲットを使用しました。

 useminPrepare: {
        target1 : {
                src : ['target1/*.html'],
                options : {
                    dest: 'out'
                }
            },

            target2 : {
                src : ['target2/folder/*.html'],
                options : {
                    dest: 'out/subfolder'
                }
            }
    },

次に、HTMLブロックでこれを行うことができます。

<!-- build:js ../subfolder/script.js -->
<script src="../subfolder/scripts/main.js></script>
<!-- endbuild -->
1
franksprings

相対パスのバグ修正を行いました。 https://www.npmjs.com/package/grunt-usemin-fix

Use-minのソースへの変更をコピーして貼り付け、相対パスを使用できます

0
greensuisse

私はこれについて多くの質問を見てきましたが、実際の答えはありません。私のプロジェクトでは、「dist」フォルダーを「/ static」サーバー側にマップしました。したがって、index.htmlで相対パスを特定する必要はありません。

しかし、それでも問題はuseminに残ります

<!-- build:css(.tmp) static/css/main.css -->
<link rel="stylesheet" href="css/main.css">
<!-- endbuild -->

useminファイルはdist/static/css/main.cssで書き込まれます

そしてHTMLは間違った(しかし期待された)パスを表示します

<link rel="stylesheet" href="static/css/main.css">

私が見つけた唯一の回避策は、useminブロックに触れないで、gruntを実行し、パスを手動で更新することです。

0
mahery rafara

テンプレートを基準にuseminブロックを作成します。

私はこのような構造を持っています:

app/ - webroot source (devmode)
app/views/layouts - layouts for server-generated pages (also has usermin tags init)
app/js - source javascript

dist/ - production build dir

私は私のhtmlをapp/layouts/main.htmlで次のように見せます:

    <!-- build:js js/static.min.js -->
      <script src="../../js/controllers/StaticCtrl.js"></script>
      <script src="../../js/directives/backImg.js"></script>
      <script src="../../js/smooth-scroll.js"></script>
    <!-- endbuild -->

on dev(useminではなく、ファイルを提供するだけ) "../../"は巧妙に "/"に解決されるだけなので、引き続き機能します。この方法では、開発中に前処理を行う必要がありません(監視タスクなどを使用)。

0
konsumer

私があなたの質問を正しく理解しているなら、「ルート」オプションが必要だと思います:

{
  useminPrepare: {
    html: 'html/index.html',
    options: {
    root: 'app'
    dest: 'dist'
    }
  }
}

Index.htmlはhtml /フォルダーにありますが、ファイルの検索はhtml /ではなくapp /から行われます

0
Rudi Starcevic
useminPrepare: {
        loyalty: {
            src: '<%= loyalty.app %>/Views/index.tpl',
            options: {
                dest: '.',
                flow: {
                    html: {
                        steps: {
                            js: ['concat', 'uglifyjs'],
                            css: ['cssmin']
                        },
                        post: {}
                    }
                }
            }
        }
    },
<!-- build:css /resources/v4/css/loyalty/index.css -->
<link rel="stylesheet" href="../Resources/css/main.css">
<link rel="stylesheet" href="../Resources/css/product.css">
<link rel="stylesheet" href="../Resources/css/use_code.css">
<!-- endbuild -->

使用する '。' gruntfileの宛先として。

0
Alexander