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を介して必要なヘルプを見つけることができませんでした...
私はあなたがこのようにして必要なものを達成できると信じています:
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ファイルを維持する必要はありません。 。
私は自分のGrunt足場を構築していたが、この問題に不満を感じていた。あなたと共有したい回避策を作成することができました。
私自身の例を使用して、彼の問題の背後にある理由と、私がどうやって対処したかを説明したいと思います。私のディレクトリ構造は次のとおりだとしましょう:
| in/
+---- pages/
| +---- login.html
+---- js/
| +---- s1.js
| +---- s2.js
+---- index.html
| out/
| Gruntfile.js
ここで、in/
はすべてのソースファイルが存在する場所であり、out/
はすべての出力ファイルが保存されるdest
ディレクトリです。 s1.js
をlogin.html
にインポートする場合、次のように記述します。
<!-- build:js ../js/login.js -->
<script src="../js/s1.js"></script>
<!-- endbuild -->
ここでは、useminブロックが単純な文字列置換を実行するため、出力パスは出力ファイルをリンクしたい場所に正確に一致する必要があります。この問題は、login.js
にout/js/login.js
で着陸する代わりに、useminPrepareがjs/login.js
で着陸する場合に発生します。これの背後にある理由は、useminPrepareは、dest
(out
)と出力パス(../js/login.js
)の間のパス結合を実行するだけですが、HTMLファイルの場所に関してパス結合を実行する必要があるためです。 。
この問題を回避するには、out/pages
が見つかった場所を尊重するdest
をlogin.html
に設定すると、問題なく機能することを確認してください。ただし、index.html
がjs/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はすべての愚かな回避策を処理します。
これが役に立てば幸いです!
私の解決策は、手動で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番目の値を使用してファイルを検索し、それが相対パスであるかどうかを確認します。
以下に示すように、複数のターゲットを使用しました。
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 -->
相対パスのバグ修正を行いました。 https://www.npmjs.com/package/grunt-usemin-fix
Use-minのソースへの変更をコピーして貼り付け、相対パスを使用できます
私はこれについて多くの質問を見てきましたが、実際の答えはありません。私のプロジェクトでは、「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を実行し、パスを手動で更新することです。
テンプレートを基準に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ではなく、ファイルを提供するだけ) "../../"は巧妙に "/"に解決されるだけなので、引き続き機能します。この方法では、開発中に前処理を行う必要がありません(監視タスクなどを使用)。
私があなたの質問を正しく理解しているなら、「ルート」オプションが必要だと思います:
{
useminPrepare: {
html: 'html/index.html',
options: {
root: 'app'
dest: 'dist'
}
}
}
Index.htmlはhtml /フォルダーにありますが、ファイルの検索はhtml /ではなくapp /から行われます
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の宛先として。