Webpack プロジェクトのテンプレート エンジンとしてからejs
に移行することにしました。pug
そして、私が必要としているのは、事前にコンパイルされた静的出力です (dev または prod モードのいずれかで)。さらに、コンパイル プロセスを通じてデータをテンプレートに渡す必要があり、そのためhtmlWebpackPlugin
にカスタム オプションを使用します。プロジェクトの構造は次のとおりです。
root
|--package.json
|--webpack.configs // .dev.js, build.js
|--data.json
|--layout.pug
|--app
|--|--index.js
|--|--views
|--|--|--index.pug
|--|--|--includes
|--|--|--|--nav.pug
|--|--|--|--footer.pug
|--assets
|--|--(styles, images...)
私が見つけて試した最初の方法は、エントリ ポイントにデータを渡すことです (でローカルをコンパイルしindex.js
、を介してページに挿入しますinnerHTML =
)。この方法は、ランタイム HTML 挿入なしで 100% プリコンパイルされた静的出力が必要なため、私にはまったく適していません。そして、楽しみが始まります...
たとえば、ナビゲーションを作成する必要があります。次のようなナビゲーションのスキーマがあります。
module.exports.nav = [
{
text: 'Home',
href: '/'
},
{
text: 'Offers',
href: '/offers.html'
},
{
text: 'Subnav Parent Test',
isSubnavTrigger: true
},
{
text: 'Subnav Item',
href: '/test.html',
isSubnavItem: true,
subnavParent: 'Subnav Parent Test'
}
]
そしてこれのためにパーシャルパグapp/views/includes/nav.pug
:
nav.navbar(role="navigation", ariaLabel="navigation")
.container
.navbar-brand
a.navbar-item(href="/")
img(src="/assets/images/logo.png", alt=title)
.navbar-menu(id="navbar-menu")
.navbar-start
.navbar-end
for link, index in nav
//- TODO: isActive
if !link.isSubnavTrigger && !link.isSubnavItem
a(href=link.href, class="navbar-item")= link.text
else if link.isSubnavTrigger
.navbar-item.has-dropdown.is-hoverable
a.navbar-link= link.text
.navbar-dropdown
- var parent = link.text
- var dd = nav.filter(_item => _item.subnavParent ===
parent)
each dd_link in dd
a.navbar-item(href=dd_link.href)= dd_link.text
そのパーシャルは共通のレイアウトに含まれていますlayout.pug
:
- var { title, nav } = htmlWebpackPlugin.options;
<!DOCTYPE html>
html(lang="en")
head
title= title + 'Pug Webpack Test'
block metas
body
header
include ./app/views/includes/nav.pug
main
block content
footer
include ./app/views/includes/footer.pug
変数app/views/includes/nav.pug
を補間することを期待して。nav
module -> rules -> loader
したがって、HTMLWebpackPlugin への使用とインライン ローダーの2 つのケースを発見しました。
1番目。webpack.config.js
設定:
module.exports = {
module: {
rules: [
//...
{
test: /\.pug$/,
use: ['file-loader?name=[path][name].html', 'pug-html-loader?pretty&exports=false']
}
//...
],
},
plugins: [
//...
new HtmlWebpackPlugin({
template: './layout.pug',
filename: 'index.html',
title: 'siteTitle',
nav: nav // required somewhere at the top of the file
})
]
}
この場合、オプションhtmlWebpackPlugin
をテンプレートに渡すことができません。で述べたように、オプションからフィールドとフィールドlayout.pug
を破棄しようとすると、コンパイル エラーが発生します。title
nav
Cannot read property 'options' of undefined
2番目のケース。webpack.config.js
:
module.exports = {
module: {
rules: [
//...
// Removed PUG loaders
//...
],
},
plugins: [
//...
new HtmlWebpackPlugin({
template: '!!pug-loader!./layout.pug', // <- inlined loader
filename: 'index.html',
title: 'siteTitle',
nav: nav // required somewhere at the top of the file
})
]
}
// by the way, in case of EJS I've been using exactly this approach
// and it worked out pretty well with partials
このアプローチは、含まれるパーシャルが含まれなくなるまで、layout.pug
から取得したオプションで完全にコンパイルされます。そして、対応するパーシャルに my を渡し、そこから nav をレンダリングする必要があります。そして、理解できず、ローダーが必要であるかのように、部分的にコンパイルにエラーをスローし始めます。htmlWebpackPlugin
nav
pug
ERROR in ./app/views/includes/nav.pug 13:12
Module parse failed: Unexpected token (13:12)
You may need an appropriate loader to handle this file type.
| .navbar-start
| .navbar-end
> for link, index in nav
| //- TODO: isActive
| if !link.isSubnavTrigger && !link.isSubnavItem
@ ./app/views/index.pug (c:/_npmg/node_modules/pug-loader!./app/views/index.pug) 4:514-543
私は完全に混乱しています。引き返すejs
気はありませんが、答えが見つからない場合は引き返す必要があるようです。
よろしくお願いします。